如何在单个SELECT语句中查询多日期范围结果做同期对比
实现方法
直接用条件聚合就可以在单条SELECT语句中同时返回两个时段的统计结果,比多次查询+UNION拼接的方式性能更好,结果也更方便直接做对比。
核心调整逻辑:
- 将WHERE子句的时间过滤范围放宽到同时覆盖「2021年1-2月」和「今年同周期」两个区间,提前过滤无关数据减少扫描量
- 用
CASE WHEN判断每行数据所属的统计周期,分别做SUM聚合,直接输出两个周期的汇总值 - 建议把原语句里的隐式逗号连接改成显式
INNER JOIN,可读性更强,也能避免漏写连接条件导致的笛卡尔积问题 - 今年的周期用日期函数动态计算,不需要硬编码年份,后续跨年查询也不用手动修改时间值
列并排对比写法(最常用,直接看两个周期数值差)
SELECT pn.no, pn.nome, -- 2021年周期统计值 SUM(CASE WHEN st.fdata > '2021-01-01' AND st.fdata < '2021-03-01' THEN st.qtt ELSE 0 END) AS qtt_2021, -- 今年同周期统计值,动态计算时间范围 SUM(CASE WHEN st.fdata > DATE_TRUNC('year', CURRENT_DATE) AND st.fdata < DATE_TRUNC('year', CURRENT_DATE) + INTERVAL '2 months' THEN st.qtt ELSE 0 END) AS qtt_current_year FROM pn INNER JOIN st ON pn.ref = st.ref WHERE st.forref LIKE '%product%' AND ( (st.fdata > '2021-01-01' AND st.fdata < '2021-03-01') OR (st.fdata > DATE_TRUNC('year', CURRENT_DATE) AND st.fdata < DATE_TRUNC('year', CURRENT_DATE) + INTERVAL '2 months') ) GROUP BY pn.no, pn.nome;
适配说明
- 如果使用MySQL数据库,把日期计算部分替换为MySQL语法即可:将
DATE_TRUNC('year', CURRENT_DATE)替换为MAKEDATE(YEAR(CURDATE()), 1),时间间隔部分替换为DATE_ADD(MAKEDATE(YEAR(CURDATE()),1), INTERVAL 2 MONTH) - 如果需要直接计算差值、同比增幅,可以直接基于两个聚合字段扩展计算,比如新增
(qtt_current_year - qtt_2021) AS diff_qtt计算数值差,ROUND((qtt_current_year / qtt_2021 - 1)*100, 2) AS growth_rate_pct计算同比增幅百分比。
行式拆分展示写法
如果你需要两个周期的结果分多行展示,可以给数据打周期标签后分组统计:
SELECT pn.no, pn.nome, CASE WHEN st.fdata > '2021-01-01' AND st.fdata < '2021-03-01' THEN '2021年同期' WHEN st.fdata > DATE_TRUNC('year', CURRENT_DATE) AND st.fdata < DATE_TRUNC('year', CURRENT_DATE) + INTERVAL '2 months' THEN '今年统计周期' END AS stat_period, SUM(st.qtt) AS total_qtt FROM pn INNER JOIN st ON pn.ref = st.ref WHERE st.forref LIKE '%product%' AND ( (st.fdata > '2021-01-01' AND st.fdata < '2021-03-01') OR (st.fdata > DATE_TRUNC('year', CURRENT_DATE) AND st.fdata < DATE_TRUNC('year', CURRENT_DATE) + INTERVAL '2 months') ) GROUP BY pn.no, pn.nome, stat_period;
内容的提问来源于stack exchange,提问作者questionador
相关产品推荐
相关产品推荐

