mysql - 连接表 (SQL)

标签 mysql sql postgresql

我是 SQL 新手,我有一个问题。我在 Postgresql 工作。 我的 table 看起来像

改变

     id action_id(fk)   field_id(fk)    old_value   new_value   
------------------------------------------------------------------
      39      15              14                           testPool
      40      15              15                           testSystem 
      41      15              16                           61019

行动

     id  description       audited_table     audited_row      audited_type  
-----------------------------------------------------------------------------
     15  Added system       systemtable        61019          insert

字段

      id       audited_table                name    
---------------------------------------------------------------------------
      14       systemtable                 pool
      15       systemtable                 storagesystem
      15       systemtable                 id

我想编写一个查询来获取以下 View

  id        description                  audited_table               audited_row      audited_type   field.name1     name1->new_value  field.name2     name2->new_value
-----------------------------------------------------------------------------------------------------------------------------------------------------------
  15        Added system                 systemtable                 61019              insert         pool            testPool        storagesystem    testSystem

基本上我想展平(行变成列)“更改”表并将其与“操作”表连接。请注意,“更改”表格对“操作”和“字段”表格的引用

架构图如下所示

感谢任何帮助,谢谢

enter image description here

最佳答案

实际上并不完全清楚您想要什么,但让我尝试回答。

首先让我们创建表和示例数据:

SQL Fiddle

PostgreSQL 9.1.9 架构设置:

CREATE TABLE Change
    ("id" int, "action_id" int, "field_id" int, "old_value" varchar(10), "new_value" varchar(10))
;

INSERT INTO Change
    ("id", "action_id", "field_id", "old_value", "new_value")
VALUES
    (39, 15, 14,'', 'testPool'),
    (40, 15, 15,'', 'testSystem'),
    (41, 15, 16,'', '61019')
;

CREATE TABLE Action
    ("id" int, "description" varchar(12), "audited_table" varchar(11), "audited_row" int, "audited_type" varchar(6))
;

INSERT INTO Action
    ("id", "description", "audited_table", "audited_row", "audited_type")
VALUES
    (15, 'Added system', 'systemtable', 61019, 'insert')
;

CREATE TABLE Field
    ("id" int, "audited_table" varchar(11), "name" varchar(13))
;

INSERT INTO Field
    ("id", "audited_table", "name")
VALUES
    (14, 'systemtable', 'pool'),
    (15, 'systemtable', 'storagesystem'),
    (15, 'systemtable', 'id')
;

如果您的问题是关于如何连接表格,答案相当简单:

查询 1:

SELECT C.id,
       A.description,
       F.audited_table,
       A.audited_row,
       A.audited_type,
       F.name AS field_name,
       C.new_value
  FROM Change AS C
  JOIN Action AS A
    ON C.action_id = A.id
  JOIN Field AS F
    ON C.field_id = F.id;

<强> Results :

| ID |  DESCRIPTION | AUDITED_TABLE | AUDITED_ROW | AUDITED_TYPE |    FIELD_NAME |  NEW_VALUE |
|----|--------------|---------------|-------------|--------------|---------------|------------|
| 39 | Added system |   systemtable |       61019 |       insert |          pool |   testPool |
| 40 | Added system |   systemtable |       61019 |       insert | storagesystem | testSystem |
| 40 | Added system |   systemtable |       61019 |       insert |            id | testSystem |

有关联接的更多信息,请查看我的博客系列:sqlity.net/en/1146/a-join-a-day-introduction/ 它基于 SQL Server,但其中的大部分信息独立于您正在使用的 RDBMS。

<小时/>

如果您试图将多行变成一行,那么您正在寻找一个枢轴。 您可以通过将行分组在一起来执行数据透视,然后使用 MAX() 和 CASE 的组合来挑选单个值。您的问题的问题是您没有指定字段“field1”与“field2”的区别。为了解决这个问题,我使用 ROW_NUMBER() 函数按照 field_id 的顺序向字段添加了编号。这样,第一个字段就是 field_id 最小的字段。枢轴现在看起来像这样:

查询 2:

SELECT action_id,
       audited_table,
       MAX(CASE WHEN field_number = 1 THEN name END) AS f1_name,
       MAX(CASE WHEN field_number = 1 THEN new_value END) AS f1_new_value,
       MAX(CASE WHEN field_number = 2 THEN name END) AS f2_name,
       MAX(CASE WHEN field_number = 2 THEN new_value END) AS f2_new_value
  FROM(
    SELECT *,ROW_NUMBER()OVER(PARTITION BY C.action_id, F.audited_table ORDER BY F.id) field_number
      FROM Change AS C
      JOIN Field AS F
        ON C.field_id = F.id
    )X
 GROUP BY action_id, audited_table;

<强> Results :

| ACTION_ID | AUDITED_TABLE | F1_NAME | F1_NEW_VALUE | F2_NAME | F2_NEW_VALUE |
|-----------|---------------|---------|--------------|---------|--------------|
|        15 |   systemtable |    pool |     testPool |      id |   testSystem |

查询 2 仅获取 Field 和 Change 表的信息。为了还获取操作信息,我们需要添加另一个联接:

查询 3:

SELECT A.id,
       A.description,
       X2.audited_table,
       A.audited_row,
       A.audited_type,
       X2.f1_name,
       X2.f1_new_value,
       X2.f2_name,
       X2.f2_new_value
  FROM Action AS A
  JOIN (
    SELECT action_id,
           audited_table,
           MAX(CASE WHEN field_number = 1 THEN name END) AS f1_name,
           MAX(CASE WHEN field_number = 1 THEN new_value END) AS f1_new_value,
           MAX(CASE WHEN field_number = 2 THEN name END) AS f2_name,
           MAX(CASE WHEN field_number = 2 THEN new_value END) AS f2_new_value
      FROM(
        SELECT *,ROW_NUMBER()OVER(PARTITION BY C.action_id, F.audited_table ORDER BY F.id) field_number
          FROM Change AS C
          JOIN Field AS F
            ON C.field_id = F.id
        )X1
     GROUP BY action_id, audited_table
  )X2  
  ON A.id = X2.action_id

<强> Results :

| ID |  DESCRIPTION | AUDITED_TABLE | AUDITED_ROW | AUDITED_TYPE | F1_NAME | F1_NEW_VALUE | F2_NAME | F2_NEW_VALUE |
|----|--------------|---------------|-------------|--------------|---------|--------------|---------|--------------|
| 15 | Added system |   systemtable |       61019 |       insert |    pool |     testPool |      id |   testSystem |

我希望这能回答您的问题。

关于mysql - 连接表 (SQL),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19416601/

相关文章:

python - 在 SQLAlchemy ORM 中,如何获取在 session.query().group_by() 中使用的主键列?

sql - 用于更新列的递归 PostgreSQL 查询

java - 我如何转义冒号( :) in a mysql query over jdbc that contains a variable assignment?

mysql - 两个表上的 GROUP_CONCAT

sql - 在 sql 中添加额外的列以显示与上一行的比率

database - PostgreSQL:如何将数据从一个数据库表复制到另一个数据库

php pdo mysql 未找到

MySQL Select - 帮助从 2 列中选择最新行

MySQL 与额外条件合并

mysql - 价格是 float 还是小数?