Return 同一行多个子表的数据
Return data from multiple child tables in same row
我有一些通过外键关联的表,我需要从中获取数据,它们的结构类似于:
Table A Intermediate A Child A
| id | Data | idTableA | idChildA | id | Child A
| 1 | 'Data 1' | 1 | 1 | 1 | 'Child 1'
| 2 | 'Data 2' | 1 | 2 | 2 | 'Child 2'
| 3 | 'Data 3' | 1 | 3 | 3 | 'Child 3'
| 2 | 4 (...)
| 2 | 5
| 3 | 6
| 3 | 6
Intermediate B Child B
| idTableA | idChildB | id | Child B
| 1 | 4 | 4 | 'Child 1'
| 1 | 5 | 5 | 'Child 2'
| 1 | 6 | 6 | 'Child 3'
| 2 | 6 (...)
| 2 | 7
| 3 | 8
| 3 | 9
我想做的是从两个子表中获取与中间表中的 Table A
键一致但不合并数据的所有记录。像这样:
Result
|idTableA|ChildA |Child B |
|1 |'Child1'|null |
|1 |'Child2'|null |
|1 |'Child3'|null |
|1 |null |'Child4'|
|1 |null |'Child5'|
|1 |null |'Child6'|
|2 |'Child4'|null |
|2 |'Child5'|null |
|2 |null |'Child6'|
|2 |null |'Child7'|
(...)
我一直在申请中间表,然后从中间表申请到子表,但未能成功地从我应该获取空值的子表中检索混合数据。
有什么想法吗?
您应该 select 来自单独 child table 的行,然后在这两个子句之间执行 UNION
,指定 NULL
其他字段 child table:
SELECT main1.id AS idTableA, ca.childA, NULL::text AS childB
FROM tableA main1
JOIN intermediateA ia ON main1.id = ia.idTableA
JOIN childA ca ON ca.id = ia.idChildA
UNION
SELECT main2.id AS idTableA, NULL, cb.childB
FROM tableA main2
JOIN intermediateB ib ON main2.id = ib.idTableA
JOIN childB cb ON cb.id = ib.idChildB
ORDER BY 1, 2, 3;
但除非你...
- 想要包含来自 Table A 的行,而在任一子 table
中都没有相关行
- 或者您想消除 Table A 中不存在的
idTableA
值(FK 约束不可能)
...您根本不需要在查询中包含 Table A 。 (否则你需要 LEFT JOIN
。)
SELECT ia.idTableA, ca.childA, NULL::text AS childB
FROM intermediateA ia
JOIN childA ca ON ca.id = ia.idChildA
UNION ALL -- !
SELECT ib.idTableA, NULL, cb.childB
FROM intermediateB ib
JOIN childB cb ON cb.id = ib.idChildB
ORDER BY 1, 2, 3;
并做到 UNION ALL
。更便宜,而且您不想在这里尝试重复折叠。
我有一些通过外键关联的表,我需要从中获取数据,它们的结构类似于:
Table A Intermediate A Child A
| id | Data | idTableA | idChildA | id | Child A
| 1 | 'Data 1' | 1 | 1 | 1 | 'Child 1'
| 2 | 'Data 2' | 1 | 2 | 2 | 'Child 2'
| 3 | 'Data 3' | 1 | 3 | 3 | 'Child 3'
| 2 | 4 (...)
| 2 | 5
| 3 | 6
| 3 | 6
Intermediate B Child B
| idTableA | idChildB | id | Child B
| 1 | 4 | 4 | 'Child 1'
| 1 | 5 | 5 | 'Child 2'
| 1 | 6 | 6 | 'Child 3'
| 2 | 6 (...)
| 2 | 7
| 3 | 8
| 3 | 9
我想做的是从两个子表中获取与中间表中的 Table A
键一致但不合并数据的所有记录。像这样:
Result
|idTableA|ChildA |Child B |
|1 |'Child1'|null |
|1 |'Child2'|null |
|1 |'Child3'|null |
|1 |null |'Child4'|
|1 |null |'Child5'|
|1 |null |'Child6'|
|2 |'Child4'|null |
|2 |'Child5'|null |
|2 |null |'Child6'|
|2 |null |'Child7'|
(...)
我一直在申请中间表,然后从中间表申请到子表,但未能成功地从我应该获取空值的子表中检索混合数据。
有什么想法吗?
您应该 select 来自单独 child table 的行,然后在这两个子句之间执行 UNION
,指定 NULL
其他字段 child table:
SELECT main1.id AS idTableA, ca.childA, NULL::text AS childB
FROM tableA main1
JOIN intermediateA ia ON main1.id = ia.idTableA
JOIN childA ca ON ca.id = ia.idChildA
UNION
SELECT main2.id AS idTableA, NULL, cb.childB
FROM tableA main2
JOIN intermediateB ib ON main2.id = ib.idTableA
JOIN childB cb ON cb.id = ib.idChildB
ORDER BY 1, 2, 3;
但除非你...
- 想要包含来自 Table A 的行,而在任一子 table 中都没有相关行
- 或者您想消除 Table A 中不存在的
idTableA
值(FK 约束不可能)
...您根本不需要在查询中包含 Table A 。 (否则你需要 LEFT JOIN
。)
SELECT ia.idTableA, ca.childA, NULL::text AS childB
FROM intermediateA ia
JOIN childA ca ON ca.id = ia.idChildA
UNION ALL -- !
SELECT ib.idTableA, NULL, cb.childB
FROM intermediateB ib
JOIN childB cb ON cb.id = ib.idChildB
ORDER BY 1, 2, 3;
并做到 UNION ALL
。更便宜,而且您不想在这里尝试重复折叠。