You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过SQL实现多月份数据合并为宽表并去除重复项?

问题解决方案

你的问题核心是误用了CROSS JOIN——这种笛卡尔积关联会让三个表的所有行强制两两组合,必然产生大量重复行。要实现你的需求,得按维度字段精准关联,或者用聚合函数配合条件判断来提取各月金额,以下是两种可行方案:

方法一:CASE WHEN + 聚合(推荐,适配绝大多数SQL数据库)

假设你的原始数据表名为your_table(替换成实际表名),直接按维度字段分组,用CASE WHEN筛选对应月份的金额并求和:

SELECT
    CONCAT(JD_WS_CD, '_', JD_WS_SUB_CD, '_', JD_SHP_TO) AS 维度拼接,
    SUM(CASE WHEN ym = '202304' THEN amt1 ELSE 0 END) AS Mar,
    SUM(CASE WHEN ym = '202305' THEN amt1 ELSE 0 END) AS Apr,
    SUM(CASE WHEN ym = '202308' THEN amt1 ELSE 0 END) AS Aug
FROM your_table
WHERE ym IN ('202304', '202305', '202308')
GROUP BY JD_WS_CD, JD_WS_SUB_CD, JD_SHP_TO;

分组后直接得到每个维度组合对应的各月总额,完全不会产生重复行。

方法二:按维度字段做等值JOIN

如果一定要拆分月份子集查询,要通过维度字段做精确关联,而非笛卡尔积:

SELECT
    CONCAT(s.JD_WS_CD, '_', s.JD_WS_SUB_CD, '_', s.JD_SHP_TO) AS 维度拼接,
    s.amt1 AS Mar,
    a.amt1 AS Apr,
    b.amt1 AS Aug
FROM (SELECT JD_WS_CD, JD_WS_SUB_CD, JD_SHP_TO, amt1 FROM your_table WHERE ym = '202304') s
LEFT JOIN (SELECT JD_WS_CD, JD_WS_SUB_CD, JD_SHP_TO, amt1 FROM your_table WHERE ym = '202305') a
    ON s.JD_WS_CD = a.JD_WS_CD 
    AND s.JD_WS_SUB_CD = a.JD_WS_SUB_CD 
    AND s.JD_SHP_TO = a.JD_SHP_TO
LEFT JOIN (SELECT JD_WS_CD, JD_WS_SUB_CD, JD_SHP_TO, amt1 FROM your_table WHERE ym = '202308') b
    ON s.JD_WS_CD = b.JD_WS_CD 
    AND s.JD_WS_SUB_CD = b.JD_WS_SUB_CD 
    AND s.JD_SHP_TO = b.JD_SHP_TO;

用LEFT JOIN可以保证即使某个维度在某月份无数据,也能保留该行(对应金额为NULL),且不会产生重复,因为是按维度精确匹配的。

原SQL重复的原因

CROSS JOIN会把s表的每一行、a表的每一行、b表的每一行强制组合,比如s有3行、a有3行、b有3行,就会生成3×3×3=27行,自然全是重复的维度拼接字段,金额也会混乱。

内容的提问来源于stack exchange,提问作者Dipanjana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 05:12:34