如何在SQL Server中基于现有查询生成特定统计报表
报表生成SQL解决方案
问题背景
需要基于现有数据库查询结果生成特定格式的统计报表,现有查询返回包含重复项的PRO_C_NOME(对应示例中的C1)和ETS_C_NOME(对应示例中的C2)数据,需转换为按PRO_C_NOME分组,分别统计ETS_C_NOME为1、2、3的数量的报表。
原始查询语句
SELECT DISTINCT A.PRO_C_NOME, B.ETS_C_NOME FROM WETI_ETAPA_ITEM F INNER JOIN WETE_ETAPA_ITEM_EDITORS E ON E.ETE_N_ETI_N_CODIGO = F.ETI_N_CODIGO INNER JOIN WETA_ETAPA_PROCESSO H ON H.ETA_N_CODIGO = F.ETI_N_ETA_N_CODIGO INNER JOIN WIPR_ITEM_PROCESSO C ON C.IPR_N_CODIGO = F.ETI_N_IPR_N_CODIGO INNER JOIN WIWF_ITEM_WORKFLOW D ON D.IWF_N_CODIGO = C.IPR_N_IWF_N_CODIGO INNER JOIN WPRO_PROCESSO A ON A.PRO_N_CODIGO = C.IPR_N_PRO_N_CODIGO AND PRO_N_DELETED = 0 LEFT OUTER JOIN WISP_ITEM_SUBPROCESS G ON G.ISP_N_ID = F.ETI_ISP_N_ID INNER JOIN WETS_ETAPA_SLA B ON F.ETI_N_ETS_N_CODIGO = B.ETS_N_CODIGO
原始查询结果
| C1 | C2 |
|---|---|
| A | 1 |
| A | 1 |
| A | 3 |
| B | 2 |
| B | 2 |
| B | 2 |
| B | 3 |
| B | 3 |
| B | 3 |
| C | 1 |
| C | 2 |
目标报表格式
| S.1 | S.2 | S.3 | S.4 |
|---|---|---|---|
| A | 2 | 0 | 1 |
| B | 0 | 3 | 3 |
| C | 1 | 1 | 0 |
字段说明
- S.1:C1中的去重值(即
PRO_C_NOME) - S.2:对应S.1值下C2为1的数量(即
ETS_C_NOME='1'的计数) - S.3:对应S.1值下C2为2的数量(即
ETS_C_NOME='2'的计数) - S.4:对应S.1值下C2为3的数量(即
ETS_C_NOME='3'的计数)
解决方案SQL
直接在原始查询基础上,用CASE WHEN条件计数+GROUP BY分组即可实现需求,无需临时表或复杂嵌套:
SELECT A.PRO_C_NOME AS "S.1", COUNT(CASE WHEN B.ETS_C_NOME = '1' THEN 1 END) AS "S.2", COUNT(CASE WHEN B.ETS_C_NOME = '2' THEN 1 END) AS "S.3", COUNT(CASE WHEN B.ETS_C_NOME = '3' THEN 1 END) AS "S.4" FROM WETI_ETAPA_ITEM F INNER JOIN WETE_ETAPA_ITEM_EDITORS E ON E.ETE_N_ETI_N_CODIGO = F.ETI_N_CODIGO INNER JOIN WETA_ETAPA_PROCESSO H ON H.ETA_N_CODIGO = F.ETI_N_ETA_N_CODIGO INNER JOIN WIPR_ITEM_PROCESSO C ON C.IPR_N_CODIGO = F.ETI_N_IPR_N_CODIGO INNER JOIN WIWF_ITEM_WORKFLOW D ON D.IWF_N_CODIGO = C.IPR_N_IWF_N_CODIGO INNER JOIN WPRO_PROCESSO A ON A.PRO_N_CODIGO = C.IPR_N_PRO_N_CODIGO AND PRO_N_DELETED = 0 LEFT OUTER JOIN WISP_ITEM_SUBPROCESS G ON G.ISP_N_ID = F.ETI_ISP_N_ID INNER JOIN WETS_ETAPA_SLA B ON F.ETI_N_ETS_N_CODIGO = B.ETS_N_CODIGO GROUP BY A.PRO_C_NOME ORDER BY A.PRO_C_NOME;
关键说明
- 移除原始查询的
DISTINCT:因为需要统计所有符合条件的记录数量,去重会丢失有效计数信息; CASE WHEN逻辑:对ETS_C_NOME的目标值进行判断,符合条件返回1,否则返回NULL;COUNT()特性:自动忽略NULL值,刚好统计出对应值的出现次数;GROUP BY分组:按PRO_C_NOME聚合,得到每个分组的统计结果;- 可选
ORDER BY:按PRO_C_NOME排序,让结果更规整。
如果你的数据库支持,也可以用SUM(CASE ...)替代COUNT,效果完全一致:
SELECT A.PRO_C_NOME AS "S.1", SUM(CASE WHEN B.ETS_C_NOME = '1' THEN 1 ELSE 0 END) AS "S.2", SUM(CASE WHEN B.ETS_C_NOME = '2' THEN 1 ELSE 0 END) AS "S.3", SUM(CASE WHEN B.ETS_C_NOME = '3' THEN 1 ELSE 0 END) AS "S.4" FROM WETI_ETAPA_ITEM F -- 后续JOIN语句与上述一致 GROUP BY A.PRO_C_NOME ORDER BY A.PRO_C_NOME;
内容的提问来源于stack exchange,提问作者Leko
相关产品推荐
相关产品推荐

