从 SQL Server 中的日期检索年份和周数

Posted

技术标签:

【中文标题】从 SQL Server 中的日期检索年份和周数【英文标题】:Retrieve Year and week number from date in 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 周...这一切都取决于一年中第一周的定义。 【参考方案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))

【讨论】:

以上是关于从 SQL Server 中的日期检索年份和周数的主要内容,如果未能解决你的问题,请参考以下文章

转换日期:从年份和周数转换为日期时间

从T-SQL中的周数中获取日期

Redshift:提取给定星期和年份的星期六日期

动态计算截至该日期的财政年度结束和周数

SQL ORACLE 从多个日期时间行中获取周数

从周数获取周开始日期和周结束日期