Sql server 获取12月31日的正确周数

Sql server 获取12月31日的正确周数,sql-server,tsql,Sql Server,Tsql,在SQL Server中,我试图获取给定日期的周数(带有年份),欧式,因此我使用DATEPART和ISO_week参数: SELECT CAST(DATEPART(year, myDate) AS VARCHAR) + RIGHT('0' + CAST(DATEPART(ISO_WEEK, myDate) AS VARCHAR), 2); 除了2018年12月31日(2019年第一周)外,这项功能运行良好,但由于我将年度和周分别使用DATEPART,因此显然无法运行。以下是myDate为201

在SQL Server中,我试图获取给定日期的周数(带有年份),欧式,因此我使用
DATEPART
ISO_week
参数:

SELECT CAST(DATEPART(year, myDate) AS VARCHAR) + RIGHT('0' + CAST(DATEPART(ISO_WEEK, myDate) AS VARCHAR), 2);
除了2018年12月31日(2019年第一周)外,这项功能运行良好,但由于我将年度和周分别使用
DATEPART
,因此显然无法运行。以下是myDate为2018年12月31日时的一个示例:

SELECT CAST(DATEPART(year, '31-12-2018') AS VARCHAR) + RIGHT('0' + CAST(DATEPART(ISO_WEEK, '31-12-2018') AS VARCHAR), 2);
上述查询返回“201801”


有没有办法在2018年12月31日获得201901,而无需对该日期进行明确测试?

问题在于,有一种独特的情况,即周数可能在一年中非常“早”,尽管实际上是12月,因此很容易检查是否在12月开始一周,在这种情况下,只需在一年中增加一个

DECLARE @mydate as datetime2 = '20270101';
SELECT CAST(DATEPART(year, @myDate) 
            + case when DATEPART(ISO_WEEK, @myDate) < 2 and month(@mydate) =12 then 
                                                      1 
                                                 else 
                                                       0 
                                                 end   

             + case when DATEPART(ISO_WEEK, @myDate) >10 and month(@mydate) =1 then 
                                                  -1 
                                             else 
                                                   0 
                                             end 
AS VARCHAR) 
              + RIGHT('0' + CAST(DATEPART(ISO_WEEK, @myDate) AS VARCHAR), 2);
将@mydate声明为datetime2='20270101';
选择CAST(DATEPART(year,@myDate)
+当DATEPART(ISO_WEEK,@myDate)<2且月份(@myDate)=12时,则为
1.
其他的
0
结束
+当DATEPART(ISO_WEEK,@myDate)>10且月份(@myDate)=1时
-1 
其他的
0
结束
AS VARCHAR)
+右('0'+演员阵容(日期部分(ISO_WEEK,@myDate)为VARCHAR),2);

我为另一个答案中突出显示的2027问题添加了一个更正。

检查以下查询,它使用一周的最后一天来获取年份值

SELECT CAST(DATEPART(year, DATEADD(wk, 1, DATEADD(DAY, 0-DATEPART(WEEKDAY, '2018-12-31'), DATEDIFF(dd, 0, '2018-12-31')))) AS VARCHAR) + RIGHT('0' + CAST(DATEPART(ISO_WEEK, '2018-12-31') AS VARCHAR), 2);

请参阅可能的重复参考和稍微整理:

declare @d datetime = '2018-12-31';
select cast(year(dateadd(day, 26 - datepart(ISO_WEEK, @d), @d)) as varchar(4)) + right(('0' + cast(datepart(ISO_WEEK, @d) as varchar(2))), 2)
结果显示
201901

测试代码:

select cast(ds.d as date) as 'date', cast(year(dateadd(day, 26 - datepart(ISO_WEEK, ds.d), ds.d)) as varchar(4)) + right(('0' + cast(datepart(ISO_WEEK, ds.d) as varchar(2))), 2) as "IsoWeek"
from (
    select dateadd(day, x.num, '2018-12-30') as d
    from (
        select h.num + d.num + s.num as num
        from (
            select 0 num union select 100 num union select 200 num union select 300 num
        ) h
        cross join (
            select 0 num union select 10 num union select 20 num union select 30 num
        ) d
        cross join (
            select 0 num union select 1 num union select 2 union select 3 num
        ) s
    ) x    
) ds
order by ds.d
其结果是:

date IsoWeek 2018-12-30 201852 2018-12-31 201901 2019-01-01 201901 2019-01-02 201901 2019-01-09 201902 2019-01-10 201902 2019-01-11 201902 2019-01-12 201902 2019-01-19 201903 2019-01-20 201903 2019-01-21 201904 2019-01-22 201904 2019-01-29 201905 2019-01-30 201905 2019-01-31 201905 2019-02-01 201905 2019-04-09 201915 2019-04-10 201915 2019-04-11 201915 2019-04-12 201915 2019-04-19 201916 2019-04-20 201916 2019-04-21 201916 2019-04-22 201917 2019-04-29 201918 2019-04-30 201918 2019-05-01 201918 2019-05-02 201918 2019-05-09 201919 2019-05-10 201919 2019-05-11 201919 2019-05-12 201919 2019-07-18 201929 2019-07-19 201929 2019-07-20 201929 2019-07-21 201929 2019-07-28 201930 2019-07-29 201931 2019-07-30 201931 2019-07-31 201931 2019-08-07 201932 2019-08-08 201932 2019-08-09 201932 2019-08-10 201932 2019-08-17 201933 2019-08-18 201933 2019-08-19 201934 2019-08-20 201934 2019-10-26 201943 2019-10-27 201943 2019-10-28 201944 2019-10-29 201944 2019-11-05 201945 2019-11-06 201945 2019-11-07 201945 2019-11-08 201945 2019-11-15 201946 2019-11-16 201946 2019-11-17 201946 2019-11-18 201947 2019-11-25 201948 2019-11-26 201948 2019-11-27 201948 2019-11-28 201948 日期等周 2018-12-30 201852 2018-12-31 201901 2019-01-01 201901 2019-01-02 201901 2019-01-09 201902 2019-01-10 201902 2019-01-11 201902 2019-01-12 201902 2019-01-19 201903 2019-01-20 201903 2019-01-21 201904 2019-01-22 201904 2019-01-29 201905 2019-01-30 201905 2019-01-31 201905 2019-02-01 201905 2019-04-09 201915 2019-04-10 201915 2019-04-11 201915 2019-04-12 201915 2019-04-19 201916 2019-04-20 201916 2019-04-21 201916 2019-04-22 201917 2019-04-29 201918 2019-04-30 201918 2019-05-01 201918 2019-05-02 201918 2019-05-09 201919 2019-05-10 201919 2019-05-11 201919 2019-05-12 201919 2019-07-18 201929 2019-07-19 201929 2019-07-20 201929 2019-07-21 201929 2019-07-28 201930 2019-07-29 201931 2019-07-30 201931 2019-07-31 201931 2019-08-07 201932 2019-08-08 201932 2019-08-09 201932 2019-08-10 201932 2019-08-17 201933 2019-08-18 201933 2019-08-19 201934 2019-08-20 201934 2019-10-26 201943 2019-10-27 201943 2019-10-28 201944 2019-10-29 201944 2019-11-05 201945 2019-11-06 201945 2019-11-07 201945 2019-11-08 201945 2019-11-15 201946 2019-11-16 201946 2019-11-17 201946 2019-11-18 201947 2019-11-25 201948 2019-11-26 201948 2019-11-27 201948 2019-11-28 201948
你想要的可能的复制品是
ISO_YEAR
,它不存在,所以或类似的逻辑它工作得很好!你能解释一下这是怎么回事吗?@iMezouar这个26周数字的“魔法”是一个计算“iso年”(在一张纸上算出)的算术技巧。剩下的只是字符串处理(例如
right('0'+数字,2)
just zero pads数字:当周大于9时,将有一个三字符字符串。摘要:将其分解为子表达式子表达式。测试代码主要是通过生成一组数字并将其添加到基准日期来生成日期(主要是使用交叉连接的借口。以防他没有机会告诉你它是如何工作的(26周)如果weekNumber为53,则为负数。在这种情况下,如2027年1月1日,将减去天数,即2026年。对于2026年31月12日,也将减去天数,使该年仍在2026年。对于2018年12月31日,您将增加27天,即2018年。似乎在wron,您永远不能增加或减少太多的天数g时间和进入错误的年份,这真的很巧妙。@Richard,我的问题真的是关于(26周数)部分,Cato优雅地解释了这一部分,我在最初的查询中已经有了连接部分,交叉连接非常清楚:)谢谢大家。