SQL Server按周分组统计时日期年份错误的修正问询
问题分析与解决方案
你的问题出在两个核心点:一是构造周起始日期时错误使用了当前年份(来自GETDATE()),导致所有结果的年份被强制改成了2018;二是分组仅按周数,未结合年份,可能引发跨年份同周数的数据被错误合并。
修正后的SQL方案一(保留原周数计算逻辑)
DECLARE @s DATETIME= '2017-12-18', @e DATETIME= '2018-01-15'; SELECT ROUND(AVG(CAST(MYTABLE.score AS FLOAT)), 1) AS avgScore, -- 基于每条记录的dateCreated实际年份构造周起始日期 DATEADD(week, DATEPART(wk, dateCreated) - 1, DATEADD(yy, DATEDIFF(yy, 0, dateCreated), 0)) AS weekStartDate FROM MYTABLE WHERE MYTABLE.dateCreated BETWEEN @s AND @e -- 必须同时按年份+周数分组,避免不同年份同周数的冲突 GROUP BY DATEPART(yyyy, dateCreated), DATEPART(wk, dateCreated) ORDER BY weekStartDate;
修正后的SQL方案二(更简洁可靠)
这个方案直接计算每条记录所在周的起始日期,无需单独处理年份和周数,自动适配跨年份场景:
DECLARE @s DATETIME= '2017-12-18', @e DATETIME= '2018-01-15'; SELECT ROUND(AVG(CAST(MYTABLE.score AS FLOAT)), 1) AS avgScore, -- 取每周的周一作为起始(若需周日为周起始,把0改为-1即可) DATEADD(week, DATEDIFF(week, 0, dateCreated), 0) AS weekStartDate FROM MYTABLE WHERE MYTABLE.dateCreated BETWEEN @s AND @e -- 直接按周起始日期分组,逻辑更直观 GROUP BY DATEADD(week, DATEDIFF(week, 0, dateCreated), 0) ORDER BY weekStartDate;
原代码出错原因详解
原代码中DATEADD(yy, DATEDIFF(yy, 0, GETDATE()), 0)的作用是获取当前系统年份的1月1日,而非你数据中dateCreated字段的实际年份。这就导致无论原始数据是2017还是2018年,构造出的周起始日期都会基于2018年,最终所有结果的年份都变成了2018。
同时,仅按DATEPART(wk, dateCreated)分组存在隐患:不同年份的同一周数(比如2017年第52周和2018年第52周)会被错误合并到同一组中,加上年份的分组就能彻底避免这个问题。
内容的提问来源于stack exchange,提问作者James Privett
相关产品推荐
相关产品推荐

