我正在尝试使用 Crosstab 以垂直方式获取表数据。更精确地说,我需要同时按前缀和后缀分组并获取汇总。在这种情况下,我应该加入2个表并获取唯一前缀和后缀的名称。列数可能会有所不同,具体取决于 income_account_setting 表的值。就我而言,我有20多个不同的名称,这意味着我应该具有code_account和20列。我尝试在 Crosstab 的帮助下进行操作,但是在Internet上给出了固定列数的示例
我的桌子: main_client_profit
id | code_account | summa | prefix | postfix | oper_month |
------------------------------------------------------------------------------------
1 | 04315187 | 72871232.77 | 45233 | 222 | 2020-04 |
2 | 00524154 | 89753426.58 | 45294 | 100 | 2020-01 |
3 | 02115187 | 23224345.89 | 45249 | 204 | 2020-03 |
4 | 00388996 | 119030.87 | 45294 | 246 | 2020-05 |
5 | 04222959 | 105000.00 | 45233 | 222 | 2020-04 |
6 | 04315187 | 92871232.77 | 45233 | 222 | 2020-04 |
1 | 04222959 | 1020458.40 | 45233 | 421 | 2020-01 |
收入帐户设置
id | prefix | postfix | name |
-------------------------------------------------------------------------------------
1 | 45233 | 222 | A |
1 | 45294 | 100 | B |
1 | 45249 | 204 | C |
1 | 45294 | 246 | E |
1 | 45233 | 421 | F |
我需要取得的结果
------------------------------------------------------------------------------------
code_account | A | B | C | D | E |
----------------------------------------------------------
04315187 | 165742465 | 0 | 0 | 0 | 0 |
00524154 | | 89753426.58 | 0 | 0 | 0 |
02115187 | 0 | | 23224345.89 | 0 | 0 |
and etc ....
到目前为止我尝试过的方法,但是没有用
SELECT *
FROM crosstab('SELECT m.code_account, a.name, evaluation_result
FROM main_client_profit m
INNER JOIN income_account_setting a
ON m.prefix = a.prefix AND m.postfix = a.postfix
GROUP BY CONCAT(m.prefix,m.postfix)
ORDER BY 1,2')
AS final_result(code character varying(20),)
在上面的代码中,我不知道在final_result中将什么写为列。
是否可以使用Crosstab来完成此任务?还是有其他方法可以实现?可以提供任何帮助。
答案 0 :(得分:1)
我的观点是,crosstab()
函数通常会使事情变得更加复杂,反而会有所帮助。而且,它不能克服以下限制:必须在运行语句之前 知道结果的所有列。
我会这样:
SELECT m.code_account,
sum(m.summa) filter (where a.name = 'A') as "A",
sum(m.summa) filter (where a.name = 'B') as "B",
sum(m.summa) filter (where a.name = 'C') as "C",
sum(m.summa) filter (where a.name = 'D') as "D",
sum(m.summa) filter (where a.name = 'E') as "E"
FROM main_client_profit m
LEFT JOIN income_account_setting a
ON m.prefix = a.prefix
AND m.postfix = a.postfix
GROUP BY m.code_account
ORDER BY m.code_account
答案 1 :(得分:0)
您可以使用JSON打包/解压缩,但是您需要恢复正确的数据类型。
[这不是真正的动态,您仍然必须在列名列表中输入。因此可以通过动态SQL实现自动化]
WITH omg AS ( -- Pack into json
SELECT m.code_account
, json_object_agg(a.name, summa) AS zooi
FROM main_client_profit m
JOIN income_account_setting a
ON m.prefix = a.prefix AND m.postfix = a.postfix
GROUP BY m.code_account
ORDER BY 1
)
SELECT o.code_account -- And unpack it. Still need to cast to the wanted type
, (o.zooi->>'A')::DECIMAL(10,2) AS A
, (o.zooi->>'B')::DECIMAL(10,2) AS B
, (o.zooi->>'C')::DECIMAL(10,2) AS C
, (o.zooi->>'D')::DECIMAL(10,2) AS D
, (o.zooi->>'E')::DECIMAL(10,2) AS E
, (o.zooi->>'F')::DECIMAL(10,2) AS F
FROM omg o
ORDER BY 1
;