SQL Server如何从YYYY-ww格式的周数中获取对应周的起始与结束日期
前置说明
所有实现默认遵循ISO 8601周标准(周起始为周一,每年第一周至少包含4个当年自然日),如果你的业务周规则为周日起始,可对应调整函数参数。
- 核心逻辑:先拆分
YYYY-ww格式字符串得到年份、周数,再通过日期函数计算当周的第一天,加6天即为当周最后一天 - 不同数据库的周数计算规则存在差异,上线前建议用已知周的日期做测试验证
1. MySQL 实现
适用于MySQL 8.0及以上版本:
-- 单值查询,输入参数示例:@input_week = '2021-48' SELECT STR_TO_DATE(CONCAT(@input_week, '-1'), '%Y-%u-%w') AS week_start, -- 周起始日期(周一) DATE_ADD(STR_TO_DATE(CONCAT(@input_week, '-1'), '%Y-%u-%w'), INTERVAL 6 DAY) AS week_end; -- 周结束日期(周日)
结合你现有包含Year、WeekNo字段的表批量查询:
SELECT Year, WeekNo, STR_TO_DATE(CONCAT(Year, '-', WeekNo, '-1'), '%Y-%u-%w') AS week_start, DATE_ADD(STR_TO_DATE(CONCAT(Year, '-', WeekNo, '-1'), '%Y-%u-%w'), INTERVAL 6 DAY) AS week_end FROM 你的表名;
调整为周日起始规则:把格式符
%u换成%U,拼接的-1改为-0即可。
2. SQL Server 实现
适用于SQL Server 2016及以上版本:
-- 单值查询,输入参数示例:DECLARE @input_week VARCHAR(7) = '2021-48' SET DATEFIRST 1; -- 指定周一为一周第一天,适配ISO周规则 DECLARE @year INT = LEFT(@input_week, 4), @week INT = RIGHT(@input_week, 2); SELECT DATEADD(WEEK, @week - 1, DATEADD(DAY, 1 - DATEPART(WEEKDAY, DATEFROMPARTS(@year, 1, 1)), DATEFROMPARTS(@year, 1, 1))) AS week_start, DATEADD(DAY, 6, DATEADD(WEEK, @week - 1, DATEADD(DAY, 1 - DATEPART(WEEKDAY, DATEFROMPARTS(@year, 1, 1)), DATEFROMPARTS(@year, 1, 1)))) AS week_end;
3. PostgreSQL 实现
-- 单值查询,输入参数示例:input_week := '2021-48' SELECT to_date(input_week || '-1', 'IYYY-IW-ID') AS week_start, to_date(input_week || '-7', 'IYYY-IW-ID') AS week_end;
结合表批量查询:
SELECT "Year", "WeekNo", to_date(concat("Year", '-', "WeekNo", '-1'), 'IYYY-IW-ID') AS week_start, to_date(concat("Year", '-', "WeekNo", '-7'), 'IYYY-IW-ID') AS week_end FROM 你的表名;
存储过程示例(MySQL)
如果需要封装成存储过程重复调用,可以用以下写法:
DELIMITER // CREATE PROCEDURE GetWeekRange(IN input_week VARCHAR(7)) BEGIN SELECT STR_TO_DATE(CONCAT(input_week, '-1'), '%Y-%u-%w') AS week_start, DATE_ADD(STR_TO_DATE(CONCAT(input_week, '-1'), '%Y-%u-%w'), INTERVAL 6 DAY) AS week_end; END // DELIMITER ; -- 调用方式 CALL GetWeekRange('2021-48');
内容的提问来源于stack exchange,提问作者Bhavin
相关产品推荐
相关产品推荐

