将 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