You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 06:42:37