SQL按PlayerID统计2021年后首次及末次购买日期结果异常求助
问题原因
- 核心错误是
GROUP BY子句中包含了ddn.[Date ]字段:SQL聚合分组会按照指定的所有分组字段的唯一组合拆分结果,每个不同的ddn.[Date ]值都会生成单独的分组,所以同一个玩家会按天拆分为多行,每行的min/max日期自然只能取到当天的值。 - 日期过滤逻辑错误:你把日期过滤写在了
HAVING子句中,HAVING是对聚合后的结果进行过滤,此处应该用WHERE子句在聚合前就过滤符合要求的记录,减少不必要的计算;另外你的需求是统计2021年1月1日之后的记录,当前过滤条件是> '2020-11-26'不符合业务要求。 - 收入计算逻辑错误:
sum(ddn.Revenue + p.LifeTimeRevenue)会导致玩家的固定累计收入LifeTimeRevenue被重复累加N次(N为该玩家符合条件的每日记录条数),计算结果会远大于实际值。 - 聚合后的日期列没有设置别名,执行
into创建新表时会因为无列名报错。
修正后的SQL语句
SELECT p.PlayerID, p.InstallDate, p.Platform, p.[Country ], p.LoginType, SUM(ddn.Revenue) + MAX(p.LifeTimeRevenue) AS LTRevenueNew, -- 先加总每日收入,再叠加玩家固定历史累计收入 MIN(ddn.[Date ]) AS FirstPayDate, -- 给聚合列设置别名 MAX(ddn.[Date ]) AS LastPayDate INTO dbo.PlayersNew -- 取消注释即可生成目标新表 FROM dbo.Players p INNER JOIN dbo.DailyDataNew ddn ON p.PlayerID = ddn.PlayerID WHERE CONVERT(DATE, ddn.[Date ]) >= '2021-01-01' -- 改用WHERE提前过滤,调整为需求要求的时间节点 GROUP BY p.PlayerID, p.InstallDate, p.Platform, p.[Country ], p.LoginType -- 移除ddn.[Date ],仅按玩家维度分组
补充说明
如果业务要求仅统计2021年1月1日当天之后(不包含当天)的记录,把WHERE条件的>=改为>即可。
内容的提问来源于stack exchange,提问作者iswearnobs
相关产品推荐
相关产品推荐

