繁体   English   中英

给定星期数,返回T-SQL中的星期几

[英]Given a Week Number, Return the First Day of the Week in T-SQL

这会给我一个基于日期的星期数:

SELECT DATEPART(wk, '7/27/2016') AS [Week]

例如,返回31。

现在,我需要做的是找到该周的第一天,并以短日期格式返回它。 例如:

Given Week: 31
Return First Day of Week: July 24

要么

Given Week: 52
Return First Day of Week: Dec 25

我相信默认的一周的第一天是星期日,这就是我需要的日期。

我在这里看到了几篇接近的文章,但没有一篇让我一路走到那里。

谢谢!

我会帮助您从内到外阅读。 我添加了编号的注释以提供帮助。

declare @weekNum int;set @weeknum = 52;
select 
-- 3.  Add number of weeks
dateadd(wk, @weekNum, 
    --2.  first day of week 0 for that year (may belong to previous year)
    dateadd(ww, datediff(wk, 0, 
        --1.  First date of the year (week 0)
        dateadd(YEAR, datediff(year,0, getDate()),0)
     ),-1) -- -1 here because 1900-01-01 (date 0) was a Monday, and adding weeks to a Monday results in a Monday.
)

我们可以将步骤二和步骤三结合起来,因为它们都需要数周的时间:

declare @weekNum int;set @weeknum = 52;
select 
    --2.  first day of week 0 for that year (may belong to previous year) + number of weeks
    dateadd(ww, @weekNum + datediff(wk, 0, 
        --1.  First date of the year (week 0)
        dateadd(YEAR, datediff(year,0, getDate()),0)
     ),-1) -- -1 here because 1900-01-01 (day 0) was a Monday. Adding weeks to a Monday results in a Monday

另外,我认为您在第31周的示例减少了一周的时间。 您可以看到以下年份的完整集:

with weeks as 
(
    select top 52 row_number() over (order by  object_id) as wk  from sys.objects
)
select wk,
    --2.  first day of week 0 for that year (may belong to previous year) + number of weeks
    dateadd(ww, wk + datediff(wk, 0, 
        --1.  First date of the year (week 0)
        dateadd(YEAR, datediff(year,0, getDate()),0)
     ),-1) -- -1 here because 1900-01-01 (day 0) was a Monday. Adding weeks to a Monday results in a Monday
from weeks

这是使用DATEDIFF和DATEADD的示例(第3行是获取所需值的代码的一行)。 这可能类似于接受的答案。

我正在发布,因为这是我为自己编写文档时在函数中使用的细分。

--1. Get the number of Weeks since Monday, January 1, 1900
select DATEDIFF(wk, 0, '01/01/2016') -- 6052 Weeks

--2: Take the value since 1900 + Number of Weeks - 8 Days get you to Sunday.
select DATEADD(wk, 6052 + (31), -8);

--3. Put it all together..
select DATEADD(wk, DATEDIFF(wk, 0, '1/1/2016' ) + (31), -8); --=2016-07-24

看我的计算。 这个想法是从每年的1月1日开始进行算术运算。

declare @year int=2016, @wk int=31
--A) Single chain calculations
select case datepart(weekday,cast(concat(@year,'-01-01') as date))
            when 1 then dateadd(wk,@wk-1,cast(concat(@year,'-01-01') as date))
            else dateadd(wk,@wk-1,
                  dateadd(day, 1/*8 if you want "first full week"*/ - datepart(weekday, cast(concat(@year,'-01-01') as date)),
                          cast(concat(@year,'-01-01') as date))) end

--B) the same in a better readable form    
;with tmp as (
select  cast(concat(@year,'-01-01') as date) jan01
)
select case datepart(weekday,jan01)
            when 1 then dateadd(wk, @wk-1, jan01)
            else dateadd(wk, @wk-1, dateadd(day, 1 - datepart(weekday, jan01), jan01)) end frstDay
from tmp

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM