如何通过联接多个表来展平数据

How to flat data by joining multiple tables

提问人:user2041057 提问时间:11/15/2023 更新时间:11/16/2023 访问量:33

问:

我有三张表,如下:

T1:
+----+--------+--------+
| id | f1     | f2     |
+----+--------+--------+
| 1  | a      | c      |
| 2  | b      | d      |
+----+--------+--------+

T2:
+----+----+--------+--------+----+
| id | T1 | f1     | f2     | T3 |
+----+----+--------+--------+----+
| 1  | 1  | aa     | 100    | 1  |
| 2  | 1  | bb     | 200    | 1  |
| 3  | 2  | aa     | 56     | 2  |
| 4  | 2  | bb     | 550    | 2  |
| 5  | 2  | cc     | -120   | 3  |
+----+----+--------+--------+----+

T3:
+----+--------+--------+
| id | f4     | f5     |
+----+--------+--------+
| 1  | aaa    | x      |
| 2  | bbb    | y      |
| 3  | ccc    | z      |
+----+--------+--------+

我需要根据 T1 表平整这些表。因此,我需要一个选择查询来通过将 T1 与 T2 和 T3 连接起来来生成此结果:

+-------+----+----+-----+-----+-------------+------+-----+-----+-----+
| T1_id | f1 | f2 | aa  | bb  | sum(aa, bb) | cc   | aaa | bbb | ccc |
+-------+----+----+-----+-----+-------------+------+-----+-----+-----+
| 1     | a  | c  | 100 | 200 | 300         |      | x   |     |     |
| 2     | b  | d  | 56  | 550 | 610         | -120 |     | y   | z   |
+-------+----+----+-----+-----+-------------+------+-----+-----+-----+

我想这是一个通过表格解决的问题,但我不知道该怎么做。任何帮助将不胜感激。row as columnpivotpostgresql

SQL PostgreSQL 数据透视

评论

2赞 JNevill 11/15/2023
它总是只是值 , , in 还是值的数量是动态的?同样的问题。如果答案是“动态”,那么我不会在 postgres 中这样做。如果它始终是值的静态列表,则只需使用 CASE 表达式或透视功能单独处理每个表以按照您想要的方式塑造它,然后联接这些结果集/子查询。aabbccT2f1T3f1
0赞 user2041057 11/18/2023
@JNevill 所有字段都是动态的。此外,我简化了问题以找到主要问题的解决方案,然后对其进行调整以连接~7个或更多表。“我不会在postgres中这样做”是什么意思?你的意思是在postgres中是不可能的吗?

答:

0赞 Adesoji Alu 11/16/2023 #1

试试这个查询


SELECT
  T1.id AS T1_id,
  T1.f1,
  T1.f2,
  SUM(CASE WHEN T2.f1 = 'aa' THEN T2.f2 ELSE 0 END) AS aa,
  SUM(CASE WHEN T2.f1 = 'bb' THEN T2.f2 ELSE 0 END) AS bb,
  SUM(CASE WHEN T2.f1 = 'aa' THEN T2.f2 ELSE 0 END) +
  SUM(CASE WHEN T2.f1 = 'bb' THEN T2.f2 ELSE 0 END) AS "sum(aa, bb)",
  MAX(CASE WHEN T2.f1 = 'cc' THEN T2.f2 END) AS cc,
  MAX(CASE WHEN T3.id = 1 THEN f4 END) AS aaa,
  MAX(CASE WHEN T3.id = 2 THEN f4 END) AS bbb,
  MAX(CASE WHEN T3.id = 3 THEN f4 END) AS ccc,
  MAX(CASE WHEN T3.id = 1 THEN f5 END) AS x,
  MAX(CASE WHEN T3.id = 2 THEN f5 END) AS y,
  MAX(CASE WHEN T3.id = 3 THEN f5 END) AS z
FROM T1
LEFT JOIN T2 ON T1.id = T2.T1
LEFT JOIN T3 ON T2.T3 = T3.id
GROUP BY T1.id, T1.f1, T1.f2
ORDER BY T1.id;