You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

MSSQL关联表统计每日消费总额出现重复日期问题

解决每日消费总额报表的重复日期问题

你的查询核心问题出在关联逻辑导致的重复累加上,咱们一步步拆解清楚:

问题根源

你的子查询s已经按uid算出了每个订单的总金额,但你把它和完整的purchasing表做JOIN时,如果purchasing表中同一个uid存在多条记录(比如同一订单的多条状态日志、数据冗余等情况),那么这个订单的总金额会被重复关联多次。最终外部的SUM(s.Total)会把同一个订单的金额累加多遍,同时因为purchasing里的多条记录可能共享同一个日期,就会出现重复的日期行,金额数据也会严重失真。

修正后的查询方案

我们需要先确保每个uid只对应唯一的日期记录,再和订单总金额关联,最后按日期汇总。这里提供两种简洁可靠的写法:

写法1:先聚合purchasing表的uid和日期

SELECT 
    LEFT(f.order_date, 10) AS transaction_date,
    SUM(s.order_total) AS daily_total
FROM 
    (
        -- 先取出每个uid对应的唯一日期,避免同一uid多条记录干扰
        SELECT uid, LEFT(timestamp, 10) AS order_date 
        FROM dbo.purchasing 
        GROUP BY uid, LEFT(timestamp, 10)
    ) AS f
JOIN 
    (
        -- 按uid计算每个订单的总金额
        SELECT 
            uid,
            SUM(CONVERT(DECIMAL(18,2), CONVERT(DECIMAL(18,4), qty) * price)) AS order_total 
        FROM dbo.purchasingitems 
        GROUP BY uid
    ) AS s 
ON f.uid = s.uid 
GROUP BY LEFT(f.order_date, 10)

写法2:用DISTINCT筛选唯一的uid+日期

如果你的purchasing表中每个uid确实只对应一个日期,用DISTINCT会更直观:

SELECT 
    LEFT(p.timestamp, 10) AS transaction_date,
    SUM(pi.order_total) AS daily_total
FROM 
    (SELECT DISTINCT uid, timestamp FROM dbo.purchasing) AS p
JOIN 
    (
        SELECT 
            uid,
            SUM(CONVERT(DECIMAL(18,2), CAST(qty AS DECIMAL(18,4)) * price)) AS order_total 
        FROM dbo.purchasingitems 
        GROUP BY uid
    ) AS pi 
ON p.uid = pi.uid 
GROUP BY LEFT(p.timestamp, 10)

额外优化建议

  • 尽量避免用TIMESTAMP作为列名,它是SQL的保留关键字,容易引发语法问题;
  • 给列取更清晰的别名(比如transaction_datedaily_total),方便后续报表阅读和维护;
  • 如果purchasing表的timestamp本身是日期时间类型,可以直接用CAST(timestamp AS DATE)提取日期,比LEFT函数更可靠。

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

火山引擎 最新活动