如何实现单表多条件列聚合且按日期分组的SQL查询?
单表多条件列级聚合实现方案
核心结论
你设想的列级携带差异化计算条件的聚合查询完全可行,不需要拆分多个独立查询执行,通过单次扫描table1就可以一次性返回所有带分组的聚合结果,执行效率远高于拆分多查询的方案。
你参考的伪SQL存在语法位置问题:把WHERE条件直接写在聚合函数外侧的写法不符合SQL标准,会触发语法报错,实际实现时需要把条件判断嵌入聚合的计算逻辑内部,常用写法有两种:
全数据库兼容的通用写法
所有关系型数据库、数仓引擎都支持通过CASE WHEN内嵌判断实现条件拆分,示例代码:
SELECT date, -- 仅当source匹配X时累加revenue,不匹配时返回0(也可写NULL,SUM会自动跳过NULL值) SUM(CASE WHEN source = 'X' THEN revenue ELSE 0 END) AS revenue_from_x, -- 仅当source匹配Y时累加revenue SUM(CASE WHEN source = 'Y' THEN revenue ELSE 0 END) AS revenue_from_y FROM table1 GROUP BY date
支持FILTER语法的简化写法
PostgreSQL、MySQL 8.0+、ClickHouse等引擎支持SQL标准新增的FILTER子句,无需嵌套CASE WHEN,写法可读性更强,示例代码:
SELECT date, SUM(revenue) FILTER (WHERE source = 'X') AS revenue_from_x, SUM(revenue) FILTER (WHERE source = 'Y') AS revenue_from_y FROM table1 GROUP BY date
方案对比优势
- 执行效率更高:拆分独立查询的方案需要多次重复扫描同一张table1,哪怕有索引加持也会产生不必要的IO开销;单次聚合只需要遍历一次表数据,大表场景下性能差距会非常明显。
- 结果口径更稳定:单次查询输出的所有聚合列基于同一份快照数据计算,不会出现多次查询因为业务表实时写入导致的结果不一致问题。
- 适配范围更广:使用
CASE WHEN的实现方案没有数据库版本限制,从传统业务库到新式分析引擎都可直接运行,不需要做版本兼容适配。
内容的提问来源于stack exchange,提问作者Zack Widdoss
相关产品推荐
相关产品推荐

