SQL Server中年度第一个星期一

时间:2012-11-23 08:58:07

标签: sql sql-server tsql

如何使用T-SQL找到“年度第一个星期一”?

8 个答案:

答案 0 :(得分:8)

以下是发布的链接ngruson(http://sqlbump.blogspot.nl/2010/01/first-monday-of-year.html)的示例:

DECLARE @Date datetime
DECLARE @Year int = 2012

SET @Date = DATEADD(YEAR, @Year - 1900, 0)

SELECT DATEADD(DAY, (@@DATEFIRST - DATEPART(WEEKDAY, @Date) + 
    (8 - @@DATEFIRST) * 2) % 7, @Date)

以上回报:

2012-01-02 00:00:00.000

答案 1 :(得分:2)

优雅不是;)

    DECLARE @year DATETIME = '01 jan 2012'

    SELECT [Day] 
    FROM
        (
            SELECT @year [Day] UNION ALL
            SELECT DATEADD(DAY, 1, @year) UNION ALL
            SELECT DATEADD(DAY, 2, @year) UNION ALL
            SELECT DATEADD(DAY, 3, @year) UNION ALL
            SELECT DATEADD(DAY, 4, @year) UNION ALL
            SELECT DATEADD(DAY, 5, @year) UNION ALL
            SELECT DATEADD(DAY, 6, @year)
        ) x
    WHERE
        DATENAME(DW, [Day]) = 'Monday'

答案 2 :(得分:2)

    Here, 
    1) DATEPART function for finding day of week. 
Here 1=sunday,2=monday,..,7=saturday.
    2) first find out is 2(monday) in case when
 condition then get same date,
    3) if is sunday(1) then add 1 day and get next
 day date is for monday,
    4) if is not 2(monday) and greater then 2 then find 
difference between lastday(7) and add 2 days ,
 so we reach to monday date.

    Here are you change year in @year variable. Ex:

        DECLARE @Date datetime
        DECLARE @Year int = 2012

        set @Date= convert(varchar(4),@Year) + '-01-01'
        select @Date,(case when DATEPART(DW,@Date)=2 then @Date
                     when DATEPART(DW,@Date)=1 then DATEADD(day,1,@Date)
                     else DATEADD(day,7-DATEPART(DW,@Date)+2,@Date)
                      end) as MondayDateis

答案 3 :(得分:1)

以下是实现这一目标的一个例子:

http://sqlbump.blogspot.nl/2010/01/first-monday-of-year.html

答案 4 :(得分:1)

试试这个:

declare @yr int=2020
select case when datepart(weekday,dateadd(year,@yr-1900,0))=1 then dateadd(year,@yr-1900,1)
       else dateadd(dd,8-(datepart(weekday,dateadd(year,@yr-1900,0))),dateadd(year,@yr-1900,1))
end

SQL Fiddle demo

答案 5 :(得分:0)

我需要按周分组一些数据并显示每周的第一天(在我的情况下是星期日)。我使用以下方法计算一年的第一个星期日,然后您可以使用周数来获得给定日期发生的星期的开始。

DECLARE @firstSundayThisYear DATE,
    @jan1ThisYear DATE,
    @currentYear INT;

SELECT @jan1ThisYear = '01-jan-' + CAST(DATEPART(YEAR, GETDATE()) AS VARCHAR(4)),
    @currentYear = DATEPART(YEAR, GETDATE());

SET @firstSundayThisYear = DATEADD(DAY, -DATEPART(weekday, @jan1ThisYear) + 1, @jan1ThisYear);

PRINT @firstSundayThisYear

注意:@firstSundayThisYear实际上可能是去年的日期,但是当你乘以周数时它将全部解决。

答案 6 :(得分:0)

这种方法不会像1900年那样使用神奇的岁月或魔术日期。

DECLARE @first_year_day     DATE,
        @first_year_monday  DATE,
        @year               int = 2017

SET @first_year_day    = CAST('1/1/' + str(@year, 4) AS DATE)
SET @first_year_monday    = DATEADD(day, (9 - DATEPART(dw, @first_year_day)) % 7, @first_year_day)
SELECT @first_year_monday

只有将周配置为在SQL Server首选项中以星期日开始时,代码才有效。对于大多数英语安装,这是默认设置(SELECT @@ DATEFIRST在这种情况下将返回7)

答案 7 :(得分:0)

我知道这是一个8岁的问题,但以为我还是会把帽子戴上戒指

下面的第一个代码段创建了一个测试表,以证明后面的代码不会遇到任何RBAR问题。解决的方法实际上是在第二个片段的结果中填充“ FirstMondayOfYear”列的相当简短的公式。其他所有内容只是添加到演示中。不需要单独的SET,不需要CASE语句,也不需要引用DATEFIRST。

--===== Create a test table that contains random dates and times from 1900-01-01 up to and not
     -- including 2100-01-01.
   DROP TABLE IF EXISTS #MyHead
;
 SELECT TOP 100000
        SomeDateTime = RAND(CHECKSUM(NEWID()))*DATEDIFF(dd,'1900','2100')+CONVERT(DATETIME,'1900') --Inherently DATETIME
--        SomeDateTime = CONVERT(DATETIME2(7),RAND(CHECKSUM(NEWID()))*DATEDIFF(dd,'1900','2100')+CONVERT(DATETIME,'1900')) --DATETIME2()
--        SomeDateTime = CONVERT(DATE,ABS(CHECKSUM(NEWID())%DATEDIFF(dd,'1900','2100'))+CONVERT(DATETIME,'1900')) --DATE
   INTO #MyHead
   FROM      sys.all_columns ac1
  CROSS JOIN sys.all_columns ac2
;
--===== Return the first Monday for the year of each given date (and the original date) as well
     -- as a weekday name and day check for the date created by the formula.  The FirstMondayOfYear
     -- should (obviously) always be a Monday and it should always be a day of 7 or less.
   WITH cteFindMonday AS
(
 SELECT  SomeDateTime
        ,FirstMondayOfYear  = DATEADD(dd,(DATEDIFF(dd,'1753',DATENAME(yy,SomeDateTime))+6)/7*7,'1753')
   FROM #MyHead
)
 SELECT  SomeDateTime
        ,FirstMondayOfYear
        ,DoW     = DATENAME(dw,FirstMondayOfYear)
        ,IsValid =  IIF(    DATENAME(dw,FirstMondayOfYear) = 'Monday'
                        AND DATEPART(dd,FirstMondayOfYear) <= 7 
                    ,1,0)
   FROM cteFindMonday
  ORDER BY SomeDateTime
;