带转置的Postgresql求和

dba5bblo  于 2023-01-25  发布在  PostgreSQL
关注(0)|答案(1)|浏览(106)

我的输入表包含每年属于特定类别的事件的值计数。
| 事件|年份|范畴|
| - ------|- ------|- ------|
| 十六|小行星2022|A类|
| 十三|小行星2022|乙|
| 三个|小行星2022|C级|
| 一百一十三|小行星2022|第一天|
| 1个|小行星2022|第二天|
| 第二章|小行星2022|第三日|
| 五个|二○二三|A类|
| 八个|二○二三|乙|
我需要显示每年每个类别的事件总和,在特定情况下,我还需要将D1 + D2 + D3聚合在一起)。
预期输出:
| 年份|事件总数|A类|乙类|丙类|D类|
| - ------|- ------|- ------|- ------|- ------|- ------|
| 小行星2022|一百四十八|十六|十三|三个|一百一十六|
| 二○二三|十三|五个|八个|无|无|
我的尝试的主要问题来自这样一个事实,即存在来自以下方面的挑战:1-在某些类别中没有事件的年份,2-目前年份只有2,但会随着时间的推移而增长
我试着用几个视图来分解sql,但无法在未来几年预览一些类别没有值的情况。
我想有一个sql查询,处理未来的情况。
谢谢你的帮助。

mrwjdhj3

mrwjdhj31#

透视任务就是这种情况。
在您的特定情况下,CASE表达式可帮助您收集要求和的特定事件计数,然后您可以对year_values进行聚合。您可以使用LIKE运算符检测D值。

SELECT year_, 
       SUM(events_)                                              AS events_total,
       SUM(CASE WHEN category    = 'A'  THEN events_ ELSE 0 END) AS categoryA,
       SUM(CASE WHEN category    = 'B'  THEN events_ ELSE 0 END) AS categoryB,
       SUM(CASE WHEN category    = 'C'  THEN events_ ELSE 0 END) AS categoryC,
       SUM(CASE WHEN category LIKE 'D%' THEN events_ ELSE 0 END) AS categoryD
FROM tab
GROUP BY year_

检查here演示。
结合使用FILTER运算符和COALESCE函数,结果如下:

SELECT year_, 
       SUM(events_)                                               AS events_total,
       COALESCE(SUM(events_) FILTER(WHERE category    = 'A' ), 0) AS catA,
       COALESCE(SUM(events_) FILTER(WHERE category    = 'B' ), 0) AS catB,
       COALESCE(SUM(events_) FILTER(WHERE category    = 'C' ), 0) AS catC,
       COALESCE(SUM(events_) FILTER(WHERE category LIKE 'D%'), 0) AS catD
FROM tab
GROUP BY year_

查看here演示。

相关问题