将 iso_week 转换为 SQL 中的日历日期
Convert iso_week to calendar date in SQL
我一直在搜索档案,但没有找到我要找的东西 - 我很乐意提供一些指导。
我有一个数据集,我想在其中报告按提供者 (STAFFID) 和工作周划分的预约总数,后者由该周的星期一日期定义。我玩过 datepart(iso_week, appointment_date) as week_of_yr
,这让我走到了那里 - 我可以按周分组以获得正确的数字。但是,在给定 iso_week 整数(和年份)的情况下,我不知道是否有一种简单的方法来显示本周星期一的日期。
我发现 ISO8601 Convert Week Date to Calendar Date 很有帮助,尽管我不知道我是否(或如何)可以同时针对多个值自动执行该过程。
这是我的代码花絮。理想情况下,我可以在 select 语句中添加另一个表达式来显示所需的日期。
select STAFFID
, count(*) as appointment_ct
, datepart(iso_week, appointment_date) as iso_wk --this returns the week # of the year as an int
from [dbo].[view_APPT_DATA]
where program_code in ('99999')
and appointment_date >= '1/1/2016' and appointment_date <='3/31/2016'
group by iso_wk, STAFFID
我会找到 first Monday of that year 然后使用 DATEADD 将周数添加到那一天
select STAFFID
, count(*) as appointment_ct
, datepart(iso_week, appointment_date) as iso_wk --this returns the week # of the year as an int
, dateadd(week, datepart(week, DATEADD(DAY, (@@DATEFIRST - DATEPART(WEEKDAY, dateadd(year, datepart(year, appointment_date) - 1900, 0)) + (8 - @@DATEFIRST) * 2) % 7, dateadd(year, datepart(year, appointment_date) - 1900, 0))) as monday_wk
from [dbo].[view_APPT_DATA]
where program_code in ('99999')
and appointment_date >= '1/1/2016' and appointment_date <='3/31/2016'
group by iso_wk, STAFFID, monday_wk
我不太明白 cha 的查询 return 更正具有重叠周的“特殊”年份的结果。
这是我最终用来计算 iso 周到该周第一天的(内联)函数:
CREATE OR ALTER FUNCTION dbo.FN_ISOWEEK_TO_DAY (
-- ISOWeek in format YYYYWW
@pISOWeek INT
)
RETURNS TABLE AS RETURN
SELECT DATEADD(week, CAST(RIGHT(@pISOWeek, 2) AS INT) - 1
- CASE WHEN (@@DATEFIRST - DATEPART(WEEKDAY, DATEADD(YEAR, cast(LEFT(@pISOWeek, 4) AS INT) - 1900, 0)) + (8 - @@DATEFIRST) * 2) % 7 >= 4 -- means first monday is one week ahead
THEN 1 ELSE 0 END
, DATEADD(DAY, (@@DATEFIRST - DATEPART(WEEKDAY, DATEADD(YEAR, cast(LEFT(@pISOWeek, 4) AS INT) - 1900, 0)) + (8 - @@DATEFIRST) * 2) % 7, DATEADD(YEAR, cast(LEFT(@pISOWeek, 4) AS INT) - 1900, 0)))
AS firstDay
一些测试代码:
SELECT *
FROM (
SELECT 202001, 20191230
UNION ALL
SELECT 202053, 20201228
) x (dt, expectedValue)
CROSS APPLY dbo.FN_ISOWEEK_TO_DAY(x.dt) y
我一直在搜索档案,但没有找到我要找的东西 - 我很乐意提供一些指导。
我有一个数据集,我想在其中报告按提供者 (STAFFID) 和工作周划分的预约总数,后者由该周的星期一日期定义。我玩过 datepart(iso_week, appointment_date) as week_of_yr
,这让我走到了那里 - 我可以按周分组以获得正确的数字。但是,在给定 iso_week 整数(和年份)的情况下,我不知道是否有一种简单的方法来显示本周星期一的日期。
我发现 ISO8601 Convert Week Date to Calendar Date 很有帮助,尽管我不知道我是否(或如何)可以同时针对多个值自动执行该过程。
这是我的代码花絮。理想情况下,我可以在 select 语句中添加另一个表达式来显示所需的日期。
select STAFFID
, count(*) as appointment_ct
, datepart(iso_week, appointment_date) as iso_wk --this returns the week # of the year as an int
from [dbo].[view_APPT_DATA]
where program_code in ('99999')
and appointment_date >= '1/1/2016' and appointment_date <='3/31/2016'
group by iso_wk, STAFFID
我会找到 first Monday of that year 然后使用 DATEADD 将周数添加到那一天
select STAFFID
, count(*) as appointment_ct
, datepart(iso_week, appointment_date) as iso_wk --this returns the week # of the year as an int
, dateadd(week, datepart(week, DATEADD(DAY, (@@DATEFIRST - DATEPART(WEEKDAY, dateadd(year, datepart(year, appointment_date) - 1900, 0)) + (8 - @@DATEFIRST) * 2) % 7, dateadd(year, datepart(year, appointment_date) - 1900, 0))) as monday_wk
from [dbo].[view_APPT_DATA]
where program_code in ('99999')
and appointment_date >= '1/1/2016' and appointment_date <='3/31/2016'
group by iso_wk, STAFFID, monday_wk
我不太明白 cha 的查询 return 更正具有重叠周的“特殊”年份的结果。 这是我最终用来计算 iso 周到该周第一天的(内联)函数:
CREATE OR ALTER FUNCTION dbo.FN_ISOWEEK_TO_DAY (
-- ISOWeek in format YYYYWW
@pISOWeek INT
)
RETURNS TABLE AS RETURN
SELECT DATEADD(week, CAST(RIGHT(@pISOWeek, 2) AS INT) - 1
- CASE WHEN (@@DATEFIRST - DATEPART(WEEKDAY, DATEADD(YEAR, cast(LEFT(@pISOWeek, 4) AS INT) - 1900, 0)) + (8 - @@DATEFIRST) * 2) % 7 >= 4 -- means first monday is one week ahead
THEN 1 ELSE 0 END
, DATEADD(DAY, (@@DATEFIRST - DATEPART(WEEKDAY, DATEADD(YEAR, cast(LEFT(@pISOWeek, 4) AS INT) - 1900, 0)) + (8 - @@DATEFIRST) * 2) % 7, DATEADD(YEAR, cast(LEFT(@pISOWeek, 4) AS INT) - 1900, 0)))
AS firstDay
一些测试代码:
SELECT *
FROM (
SELECT 202001, 20191230
UNION ALL
SELECT 202053, 20201228
) x (dt, expectedValue)
CROSS APPLY dbo.FN_ISOWEEK_TO_DAY(x.dt) y