如何用UNION合并两个不同日期的SQL查询结果并同行展示?
解决方案:将两个日期的聚合数据合并到同一行
嘿,我来帮你搞定这个SQL合并的问题!你之前用UNION的方式之所以不符合预期,是因为UNION的作用是把两个结果集的行堆叠在一起,而不是把同一number的不同日期数据合并到同一行里——所以你会看到一行是2019年的数据加零值,另一行是2018年的数据加零值,达不到想要的效果。
下面给你两种高效的解决方法:
方法一:条件聚合(推荐,更简洁高效)
这种方法用CASE WHEN配合聚合函数,直接在一个查询里完成两个日期的数值计算,最终同一number的所有数据会合并到一行:
SELECT number, -- 计算2019-08-09的聚合值 SUM(CASE WHEN day = '2019-08-09' THEN sales ELSE 0 END) AS sales, SUM(CASE WHEN day = '2019-08-09' THEN discount ELSE 0 END) AS discount, SUM(CASE WHEN day = '2019-08-09' THEN margin ELSE 0 END) AS margin, -- 计算2018-08-10的聚合值 SUM(CASE WHEN day = '2018-08-10' THEN sales ELSE 0 END) AS sales_n1, SUM(CASE WHEN day = '2018-08-10' THEN discount ELSE 0 END) AS discount_n1, SUM(CASE WHEN day = '2018-08-10' THEN margin ELSE 0 END) AS margin_n1 FROM table_a WHERE day IN ('2019-08-09', '2018-08-10') -- 只过滤需要的日期,提升查询效率 GROUP BY number;
原理说明:
CASE WHEN会判断每行的day是否匹配目标日期,匹配时取对应字段的值,不匹配则取0- 最后通过
GROUP BY number,把同一number下所有行的计算结果聚合起来,自然就得到了同一行的两个日期数据
方法二:自连接(灵活适配复杂场景)
如果你的需求更复杂(比如后续要扩展更多日期),也可以把两个独立的聚合查询作为子表,通过number进行关联:
SELECT COALESCE(t1.number, t2.number) AS number, -- 确保即使某一侧没有数据,number也能显示 COALESCE(t1.sales, 0) AS sales, COALESCE(t1.discount, 0) AS discount, COALESCE(t1.margin, 0) AS margin, COALESCE(t2.sales, 0) AS sales_n1, COALESCE(t2.discount, 0) AS discount_n1, COALESCE(t2.margin, 0) AS margin_n1 FROM ( -- 2019-08-09的聚合数据 SELECT number, SUM(sales) AS sales, SUM(discount) AS discount, SUM(margin) AS margin FROM table_a WHERE day = '2019-08-09' GROUP BY number ) t1 FULL OUTER JOIN ( -- 用FULL OUTER JOIN保留两个日期中所有存在的number -- 2018-08-10的聚合数据 SELECT number, SUM(sales) AS sales, SUM(discount) AS discount, SUM(margin) AS margin FROM table_a WHERE day = '2018-08-10' GROUP BY number ) t2 ON t1.number = t2.number;
原理说明:
- 先分别计算两个日期的聚合结果,得到两个子表
t1和t2 - 通过
FULL OUTER JOIN关联两个子表,确保不管某number只在其中一个日期有数据,都能被保留 - 用
COALESCE把关联后出现的NULL值转换成0,避免结果中出现空值
内容的提问来源于stack exchange,提问作者S.Jackson
相关产品推荐
相关产品推荐

