SQL Server中如何按周一为周起始日汇总收入字段?
按周一为起始日汇总周收入(SQL Server)
嘿,这个需求我做报表的时候常碰到!SQL Server默认把周日当一周的第一天,要改成周一的话,得用点小技巧,下面给你两种靠谱的实现方式,按需选就行:
方法一:不依赖会话设置的通用写法(推荐)
这种方法不用改任何系统设置,不管服务器DATEFIRST是啥值都能正常工作,适合写在视图或者通用查询里:
SELECT -- 计算当前日期所在周的周一(作为周起始日) DATEADD(week, DATEDIFF(week, '1900-01-01', DATEADD(day, -1, SaleDate)), '1900-01-01') AS WeekStartDate, -- 汇总该周的总收入 SUM(Revenue) AS TotalWeeklyRevenue FROM -- 替换成你的实际表名 Sales GROUP BY -- 分组逻辑必须和SELECT里的周起始日计算完全一致 DATEADD(week, DATEDIFF(week, '1900-01-01', DATEADD(day, -1, SaleDate)), '1900-01-01') ORDER BY WeekStartDate;
逻辑拆解:
'1900-01-01'是SQL Server里一个已知的周一,用它做基准点DATEADD(day, -1, SaleDate):把日期往前推一天,这样周日会被归到前一周的计算中(不然默认会把周日算进下一周)DATEDIFF(week, '1900-01-01', ...):计算从基准周一到调整后日期的总周数- 最后用
DATEADD把周数加回基准周一,就得到了当前日期所在周的周一
方法二:先设置周起始日为周一(直观易读)
如果你是在自己的会话里执行查询(比如SSMS里跑报表),可以先把周起始日改成周一,写法更直观:
-- 会话级设置:把一周的第一天设为周一(只对当前查询窗口有效) SET DATEFIRST 1; SELECT -- 计算周起始日:周一 DATEADD(day, 1 - DATEPART(weekday, SaleDate), SaleDate) AS WeekStartDate, SUM(Revenue) AS TotalWeeklyRevenue FROM Sales GROUP BY DATEADD(day, 1 - DATEPART(weekday, SaleDate), SaleDate) ORDER BY WeekStartDate;
逻辑拆解:
SET DATEFIRST 1:告诉SQL Server,周一就是一周的第1天(默认是周日=1)DATEPART(weekday, SaleDate):此时周一返回1,周二返回2...周日返回71 - DATEPART(...):周一得到0(DATEADD后还是当天),其他日期得到负数,往前推到周一
小提醒
- 两种方法都能处理跨年周的情况(比如12月31日是周日的话,会被归到当年最后一周,而非下一年第一周)
- 确保你的日期字段(比如
SaleDate)是date或datetime类型,别存成字符串 - 如果需要展示无收入的周(比如某周没销售数据也要显示0),可以用日历表左连接查询,这属于进阶需求啦
内容的提问来源于stack exchange,提问作者michaelg
相关产品推荐
相关产品推荐

