我是 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
基本上我想展平(行变成列)“更改”表并将其与“操作”表连接。请注意,“更改”表格对“操作”和“字段”表格的引用
架构图如下所示
感谢任何帮助,谢谢
最佳答案
实际上并不完全清楚您想要什么,但让我尝试回答。
首先让我们创建表和示例数据:
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/