DB2中将多个SUM(CASE)输出整合为带月份维度列的实现方案
DB2月度数据行式输出优化方案
你的需求本质是先将宽表存储的12个月度列转为行式存储,再按维度聚合,可通过DB2原生的LATERAL + VALUES语法实现,不需要逐一枚举每个指标的12个月CASE逻辑,实现代码如下:
SELECT t.DMYEAR, t.DMPTYP, t.DMPROD, m.DMMONTH, SUM(CASE WHEN t.DMTYPE = 'COST' THEN m.MONTH_VAL ELSE 0 END) AS COST, SUM(CASE WHEN t.DMTYPE = 'RTNCST' THEN m.MONTH_VAL ELSE 0 END) AS RTNCST, -- 其余DMTYPE直接在这里加一行即可,不需要重复写12次 SUM(CASE WHEN t.DMTYPE = '自定义类型' THEN m.MONTH_VAL ELSE 0 END) AS 自定义类型 FROM DWM t -- 行转列:把12个月度列拆为12行,每行对应一个月份和对应值 CROSS JOIN LATERAL ( VALUES (1, t.DMVL01), (2, t.DMVL02), (3, t.DMVL03), (4, t.DMVL04), (5, t.DMVL05), (6, t.DMVL06), (7, t.DMVL07), (8, t.DMVL08), (9, t.DMVL09), (10, t.DMVL10), (11, t.DMVL11), (12, t.DMVL12) ) AS m(DMMONTH, MONTH_VAL) WHERE t.DMPTYP = 'M' GROUP BY t.DMYEAR, t.DMPTYP, t.DMPROD, m.DMMONTH ORDER BY t.DMYEAR, t.DMPROD, m.DMMONTH
方案优势
- 可扩展性强:后续新增DMTYPE取值仅需要新增1行聚合逻辑,不需要修改行转列部分代码
- 输出结构完全匹配需求:自带
DMMONTH字段标识1-12月,每个月、产品、财年对应唯一一行,不同数据类型为独立列 - 性能优异:
LATERAL + VALUES是DB2内置优化过的行转列实现,比多层UNION ALL拆分效率更高
如果使用的是不支持LATERAL语法的老旧DB2版本,也可以用UNION ALL的方式实现行转列,示例如下:
WITH MONTH_UNPIVOT AS ( SELECT DMYEAR,DMPTYP,DMPROD,DMTYPE,1 AS DMMONTH,DMVL01 AS MONTH_VAL FROM DWM WHERE DMPTYP='M' UNION ALL SELECT DMYEAR,DMPTYP,DMPROD,DMTYPE,2 AS DMMONTH,DMVL02 AS MONTH_VAL FROM DWM WHERE DMPTYP='M' -- 依次补充3-11月的逻辑即可 UNION ALL SELECT DMYEAR,DMPTYP,DMPROD,DMTYPE,12 AS DMMONTH,DMVL12 AS MONTH_VAL FROM DWM WHERE DMPTYP='M' ) SELECT DMYEAR,DMPTYP,DMPROD,DMMONTH, SUM(CASE WHEN DMTYPE='COST' THEN MONTH_VAL ELSE 0 END) AS COST, SUM(CASE WHEN DMTYPE='RTNCST' THEN MONTH_VAL ELSE 0 END) AS RTNCST -- 其余类型补充即可 FROM MONTH_UNPIVOT GROUP BY DMYEAR,DMPTYP,DMPROD,DMMONTH ORDER BY DMYEAR,DMPROD,DMMONTH
内容的提问来源于stack exchange,提问作者bran
相关产品推荐
相关产品推荐

