【问题标题】:Retrieve Year and week number from date in SQL Server从 SQL Server 中的日期检索年份和周数
【发布时间】:2019-01-18 05:37:52
【问题描述】:

我正在尝试以yyyyww 格式获取年份编号和星期编号,例如201901201905201911 等,我正在使用此查询来执行此操作:

declare @BeginDate datetime

set @beginDate = '2019-02-07'

select  
     concat(datepart(year, @BeginDate), right('0' + convert(varchar, datepart(week, dateadd(day, -7 , @BeginDate))), 2)) 

在 2018 年 12 月之前一直运行良好。但是当我尝试这个日期2019-01-07 时,它返回了201953,这是不正确的。但是对于所有其他值,例如 2019-01-14 等,它会正确获取周数。

那么如何准确获取全年的年周数组合

【问题讨论】:

  • 为什么要从开始日期减去 7 天?请注意,WEEK 日期部分不一定像您想象的那样干净。给定的年份可能有 52 53 周,因为 52 周只有 364 天,而一年可能有 365 或 366 天。您应该定义如何计算一周。
  • 请问您为什么有这个特殊要求?这是一个有效的问题,但对于像复合值这样普通的东西来说,这似乎是一个非常多的字符串/日期柔术。您可能能够以更好或更简单的方式获得所需的内容。
  • 2019-01-01 属于 2018 年的第 53 周...这一切都取决于一年中第一周的定义。

标签: sql sql-server sql-date-functions


【解决方案1】:

您没有考虑“年周”的定义:

根据维基百科: 第一年的一周是包含一年中的第一个星期四的那一周,或者是包含 1 月 4 日的那一周,或者是从 12 月 29 日到 1 月 4 日之间开始的那一周。

因此,如果年份从第 52 或 53 周开始,则为上一年最后一周的尾随。

所以你有:

set dateformat ymd 
set datefirst 1
declare @data as datetime
declare @year as int

set @data = cast('2017-01-01' as datetime)
set @year = case when datepart(iso_week,@data) >= 52 and month(@data) = 1 
                      then year(@data)-1 
                 when datepart(iso_week,@data) = 1 and month(@data) = 12 
                      then year(@data)+1
                      else year(@data) end

select concat (@year, right('0'+cast(datepart(iso_week,@data) as varchar(6)),2))

这个结果是201652

编辑:更新为始终有两位数的周数

【讨论】:

    【解决方案2】:

    您可以使用以下代码尝试

    SELECT concat(year('2019-01-07'),Format(datepart(day, datediff(day, 0, '2019-01-07')/7 * 7)/7 + 1 , '00') )
    

    输出

    201902
    

    SELECT concat(year('2019-01-01'),Format(DATEPART( wk, '2019-01-01')  , '00') )
    

    输出

    201901
    

    【讨论】:

    • 这段代码有问题:用2017-01-01 测试返回201704 这肯定是错误的,dbfiddle 给它:dbfiddle.uk/…
    • 现在它显示的是第 201701 周,但它仍然有问题,因为 2017 年 1 月 1 日是第 201652 周。
    • @DDS 我已经为特定格式(yyyy-mm_dd)编写了代码,因为用户询问了特定格式
    • @我见过,但这不是问题(你也可以简单地set dateformat ymd)来明确你正在使用的格式
    • 您的代码也有问题,例如 2021-01-01 即 202053,但您的代码将其报告为 202105
    【解决方案3】:

    下面的代码块不是确切的解决方案,但它绝对可以帮助你..

    SQL

    DECLARE @Dt datetime
    
    SELECT @Dt='02-21-2008'
    
    SELECT DATEPART( wk, @Dt)
    

    【讨论】:

    • 这将返回星期值,如 1,2 等。我需要它们作为 01,02 等
    • 用户格式化函数来得到预期的结果 SELECT Format(DATEPART(wk, @Dt), '00')
    【解决方案4】:

    通常,计算日期标准部分的更清晰方法是使用标准函数。 因此,我建议将 DATEPART 与 RIGHT 结合使用,以确保我们有两个从右边开始的字符:

    DECLARE @DT AS DATE = '2019-01-07'
    SELECT  CONCAT(year(@DT),
            RIGHT('0'+CONVERT(VARCHAR(2), DATEPART(wk, @DT)), 2))
    

    【讨论】:

      猜你喜欢
      • 2020-12-14
      • 1970-01-01
      • 2017-08-30
      • 1970-01-01
      • 2012-02-17
      • 1970-01-01
      • 2023-03-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多