如何实现SQL GROUP BY如同Excel透视表不重复显示同维度字段值的效果
方案1:SQL查询层面直接实现
核心是用LAG()窗口函数对比当前行和上一行的同维度值,相同则返回空字符串,必须保证查询结果按分组维度的顺序排序,否则会出现错乱。
支持MySQL8.0+、PostgreSQL、Oracle等所有支持窗口函数的数据库,示例代码如下:
WITH 聚合结果 AS ( -- 替换为你原来的GROUP BY聚合逻辑 SELECT column1, column2, column3, SUM(统计字段) AS sum FROM 业务表 GROUP BY column1, column2, column3 -- 必须按分组维度的优先级排序,不能乱序 ORDER BY column1, column2, column3 ) SELECT -- 对比上一行的column1,值相同则返回空 IF(LAG(column1) OVER(ORDER BY column1, column2, column3) = column1, '', column1) AS column1, -- 对比上一行的column2,值相同则返回空 IF(LAG(column2) OVER(ORDER BY column1, column2, column3) = column2, '', column2) AS column2, column3, sum FROM 聚合结果;
如果是不支持窗口函数的低版本MySQL,可以用用户变量实现,示例如下:
SELECT IF(@prev_col1 = column1, '', @prev_col1 := column1) AS column1, IF(@prev_col2 = column2, '', @prev_col2 := column2) AS column2, column3, sum FROM ( SELECT column1, column2, column3, SUM(统计字段) AS sum FROM 业务表 GROUP BY column1, column2, column3 ORDER BY column1, column2, column3 ) t, (SELECT @prev_col1 := '', @prev_col2 := '') init;
方案2:展示层实现(更推荐)
SQL层返回全量的重复值结果,在渲染展示的时候处理去重,不会影响数据的复用性,适用场景更广:
- 用BI工具(PowerBI、Tableau、FineBI等)的话,直接在表格组件的设置里开启「合并相同单元格」/「隐藏重复值」功能即可,原生支持透视表展示效果
- 自行开发前端页面的话,拿到接口返回的全量数据后,遍历数组对比上一行同字段的值,相同就设为空字符串再渲染表格
- 导出到Excel处理的话,直接插入透视表,按column1>column2>column3的顺序拖入行区域即可自动实现该效果
注意:如果SQL返回的结果还要用于其他数据计算、二次加工,不要在SQL层做去重处理,空值会影响后续的计算逻辑,优先在展示层实现效果。
内容的提问来源于stack exchange,提问作者Ahmet Gunduz
相关产品推荐
相关产品推荐

