如何在SQL中便捷实现以周六为周起始的2023年月周划分
以周六为周起始的月周划分(SQL Server)
你可以通过动态计算日期所属的周起始、归属月份及周数,替代手动编写区间的方式,实现需求。以下是适配你场景的SQL语句:
SET DATEFIRST 7; -- 保持默认周日为一周第一天,后续用公式计算周六起始 SELECT dtp.MAIN_CUSTOMER_NUMBER, dtp.TRN_DATE, CONCAT( DATENAME(month, tms.TargetMonthStart, 'tr-TR'), -- 土耳其语月份名 ' ', CAST(wn.WeekNumber AS VARCHAR(2)), '.hafta' ) AS WEEK_LABEL FROM BOACARD.TRN.DAILY_TRANSACTION_POOL dtp WITH (NOLOCK) CROSS APPLY ( -- 计算当前日期所在周的起始日(周六) SELECT DATEADD(day, -(DATEPART(weekday, dtp.TRN_DATE) + 6) % 7, dtp.TRN_DATE) AS WeekStart ) ws CROSS APPLY ( -- 计算周结束日(周五) SELECT DATEADD(day, 6, ws.WeekStart) AS WeekEnd ) we CROSS APPLY ( -- 确定周归属的月份:若周内大部分天数在下月,则归下月;否则归当月 SELECT CASE WHEN DATEDIFF(day, ws.WeekStart, EOMONTH(ws.WeekStart)) < 4 THEN DATEADD(month, 1, DATEADD(month, DATEDIFF(month, 0, ws.WeekStart), 0)) ELSE DATEADD(month, DATEDIFF(month, 0, ws.WeekStart), 0) END AS TargetMonthStart ) tms CROSS APPLY ( -- 计算归属月份的第一个周六 SELECT DATEADD(day, CASE DATEPART(weekday, tms.TargetMonthStart) WHEN 1 THEN 6 -- 周日,加6天到周六 WHEN 2 THEN 5 -- 周一,加5天 WHEN 3 THEN 4 WHEN 4 THEN 3 WHEN 5 THEN 2 WHEN 6 THEN 1 WHEN 7 THEN 0 -- 周六,无需加天 END, tms.TargetMonthStart ) AS FirstSatOfMonth ) fs CROSS APPLY ( -- 计算周在归属月份的编号:若周起始早于当月第一个周六,算第1周 SELECT CASE WHEN ws.WeekStart < fs.FirstSatOfMonth THEN 1 ELSE DATEDIFF(week, fs.FirstSatOfMonth, ws.WeekStart) + 1 END AS WeekNumber ) wn WHERE YEAR(dtp.TRN_DATE) = 2023; -- 仅筛选2023年数据
关键逻辑说明
- 周起始计算:通过
DATEADD和DATEPART动态算出每个交易日期对应的周六起始日,无需手动指定区间。 - 月份归属判断:如果周起始日到当月月底的天数不足4天(说明周内大部分天数在下月),就将该周归到下月,匹配你示例中跨月周的划分逻辑。
- 周数计算:先找到归属月份的第一个周六,再计算当前周是该月的第几个周;跨月的早到周直接算作归属月份的第1周。
- 土耳其语月份名:用
DATENAME的tr-TR参数直接生成土耳其语月份名称,无需手动映射。
内容的提问来源于stack exchange,提问作者mehmetturkboga
相关产品推荐
相关产品推荐

