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

多重LEFT JOIN导致SUM结果翻倍的SQL问题求助

问题原因与解决方案

问题根源

你遇到的SUM结果翻倍问题,本质是多表连接产生的笛卡尔积导致的:

  • 当同时左连接tbl_orders和tbl_revenue到日历表时,如果某一天有N条订单记录、M条收入记录,连接后会生成N×M条重复的收入行
  • 最终SUM计算时,每条收入数据会被重复统计N次(等于当天订单的数量),结果自然被放大。

解决方案

针对这个问题,有几种可行的处理方式:

1. 先聚合收入数据再连接

先对tbl_revenue按日期完成聚合,得到每天唯一的收入统计结果,再和日历表、订单表连接,避免重复行:

SELECT 
    c.dates,
    COALESCE(r.extra_in, 0) AS extra_in,
    COALESCE(r.extra_out, 0) AS extra_out
FROM tbl_calendar as c 
LEFT JOIN `tbl_orders` AS o ON c.dates = DATE(o.order_complete_time) 
LEFT JOIN (
    SELECT 
        r_date,
        SUM(CASE WHEN r_type = 0 THEN r_amount ELSE 0 END) AS extra_in,
        SUM(CASE WHEN r_type = 1 THEN r_amount ELSE 0 END) AS extra_out
    FROM tbl_revenue
    WHERE MONTH(r_date) = 10 AND YEAR(r_date) = 2023 AND r_date <= '2023-10-18'
    GROUP BY r_date
) AS r ON r.r_date = c.dates 
WHERE MONTH(c.dates) = 10 AND YEAR(c.dates) = 2023 AND c.dates <= '2023-10-18' 
GROUP BY c.dates, r.extra_in, r.extra_out
ORDER BY c.dates DESC;

2. 移除不必要的订单表连接

如果你的查询不需要使用tbl_orders中的任何字段或统计数据,直接去掉这个LEFT JOIN即可——这也是你测试后确认有效的方法。

3. 同时聚合订单与收入数据(如果需要订单统计)

如果需要同时展示当天的订单相关统计(比如订单数量),建议同时对tbl_orders按日期聚合,再和日历表、聚合后的收入表连接:

SELECT 
    c.dates,
    COALESCE(r.extra_in, 0) AS extra_in,
    COALESCE(r.extra_out, 0) AS extra_out,
    COALESCE(o.order_count, 0) AS order_count
FROM tbl_calendar as c 
LEFT JOIN (
    SELECT 
        DATE(order_complete_time) AS order_date,
        COUNT(*) AS order_count
    FROM `tbl_orders`
    WHERE MONTH(order_complete_time) = 10 AND YEAR(order_complete_time) = 2023 AND DATE(order_complete_time) <= '2023-10-18'
    GROUP BY DATE(order_complete_time)
) AS o ON c.dates = o.order_date
LEFT JOIN (
    SELECT 
        r_date,
        SUM(CASE WHEN r_type = 0 THEN r_amount ELSE 0 END) AS extra_in,
        SUM(CASE WHEN r_type = 1 THEN r_amount ELSE 0 END) AS extra_out
    FROM tbl_revenue
    WHERE MONTH(r_date) = 10 AND YEAR(r_date) = 2023 AND r_date <= '2023-10-18'
    GROUP BY r_date
) AS r ON r.r_date = c.dates 
WHERE MONTH(c.dates) = 10 AND YEAR(c.dates) = 2023 AND c.dates <= '2023-10-18' 
ORDER BY c.dates DESC;

核心逻辑

先对需要统计的表按日期做聚合,确保每个日期只有一条统计记录,再进行多表连接,就能彻底避免笛卡尔积导致的重复计算问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 13:02:27