SQL Server:如何获取过去6个月的唯一周数?
解决周数重复的问题
你遇到的重复行问题,根源在于同一个周会跨越两个月,而你的原查询把month_number也包含在结果集中——DISTINCT会把同一年份、同一周数但不同月份的行视为不同记录,所以才会出现重复。
要解决这个问题,我们可以用GROUP BY替代DISTINCT,把相同年份和周数的行归为一组,然后针对每组选择一个合适的月份(比如该周开始的月份,或者结束的月份)。
修改后的基础版查询
DECLARE @start_date DATE = DATEADD(MONTH, -6, CURRENT_TIMESTAMP) SELECT DATEPART(WEEK, DATEADD(DAY, Number, @start_date)) AS week_number, DATEPART(YEAR, DATEADD(DAY, Number, @start_date)) AS year, -- 取该周对应的第一个月份,若想显示结束月份可替换为MAX(month_number) MIN(DATEPART(MONTH, DATEADD(DAY, Number, @start_date))) AS month_number FROM master..spt_values WHERE Type = 'P' AND DATEADD(DAY, Number, @start_date) <= CURRENT_TIMESTAMP AND DATEPART(YEAR, DATEADD(DAY, Number, @start_date)) > 2019 GROUP BY DATEPART(WEEK, DATEADD(DAY, Number, @start_date)), DATEPART(YEAR, DATEADD(DAY, Number, @start_date)) ORDER BY year, week_number
进阶:用ISO周避免跨年混淆
如果你的业务逻辑遵循国际标准周(周一为一周起始,每年第一周至少包含4天),建议改用ISO_WEEK和ISO_WEEK_YEAR函数,避免跨年周的归属错误(比如2025年第一周可能从2024年12月底开始,此时日历年份是2024,但ISO周年份是2025):
DECLARE @start_date DATE = DATEADD(MONTH, -6, CURRENT_TIMESTAMP) SELECT DATEPART(ISO_WEEK, DATEADD(DAY, Number, @start_date)) AS iso_week_number, DATEPART(ISO_WEEK_YEAR, DATEADD(DAY, Number, @start_date)) AS iso_year, MIN(DATEPART(MONTH, DATEADD(DAY, Number, @start_date))) AS month_number FROM master..spt_values WHERE Type = 'P' AND DATEADD(DAY, Number, @start_date) <= CURRENT_TIMESTAMP AND DATEPART(ISO_WEEK_YEAR, DATEADD(DAY, Number, @start_date)) > 2019 GROUP BY DATEPART(ISO_WEEK, DATEADD(DAY, Number, @start_date)), DATEPART(ISO_WEEK_YEAR, DATEADD(DAY, Number, @start_date)) ORDER BY iso_year, iso_week_number
这样处理后,每个(年份/周数)组合只会出现一次,完全符合你的需求~
内容的提问来源于stack exchange,提问作者Ignacio Ambía
相关产品推荐
相关产品推荐

