在SQL中将iso_week转换为日历日期

时间:2016-04-28 23:58:47

标签: sql sql-server date iso

我一直在搜索档案而没有找到我要找的东西 - 我很乐意提供一些指导。

我有一个数据集,我希望按提供者(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

2 个答案:

答案 0 :(得分:0)

我会找到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 

答案 1 :(得分:0)

我不太明白 cha 的查询为具有重叠周的“特殊”年份返回正确结果。 这是我最终用来计算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