2012-09-19 187 views
5

我尝试过,但无法获得正确的解决方案。我想要一个列出当年所有周末日期的SQL查询。如何在SQL中获取当年的所有周末日期?

我想这个SQL查询:

WITH hier(num, lvl) AS (
    SELECT 0, 1 
      UNION ALL 
    SELECT 100, 1 
      UNION ALL 
    SELECT num + 1, lvl + 1 
    FROM hier 
    WHERE lvl < 100 
) 
SELECT lvl [Week], 
convert(date,DATEADD(dw, -DATEPART(dw, DATEADD(wk,DATEDIFF(wk,0,'12/31/'+convert(nvarchar,YEAR(getdate()))), 0)+6), 
DATEADD(wk, DATEDIFF(wk,0,'12/31/'+convert(nvarchar,YEAR(getdate()))), 0)+6) - num * 7,101) [End Date] 
FROM hier a 
where num < 52 
ORDER BY [End Date] asc 

它的输出是这样的:

Week End date 
52 2012-01-14 
51 2012-01-21 
50 2012-01-28 
49 2012-02-04 

我想日期以从头开始 - 因此,上述缺少一个周末,这是2012-07-01。另外,我希望星期数字显示为1, 2, 3...而不是52, 51...

+0

首先,定义什么*你*在本周结束日期的意思是 - 不同文化背景的不同定义这些东西。假设你的周末是周六和周日,你需要什么日期?星期六,星期日,两者?如果两者,作为单列中的两列,还是分列? –

+0

结束日期是星期六 –

回答

5

结帐this博客文章。

您的问题已详细解释。

DECLARE @Year AS INT, 
@FirstDateOfYear DATETIME, 
@LastDateOfYear DATETIME 
-- You can change @year to any year you desire 
SELECT @year = 2010 
SELECT @FirstDateOfYear = DATEADD(yyyy, @Year - 1900, 0) 
SELECT @LastDateOfYear = DATEADD(yyyy, @Year - 1900 + 1, 0) 
-- Creating Query to Prepare Year Data 
;WITH cte AS (
SELECT 1 AS DayID, 
@FirstDateOfYear AS FromDate, 
DATENAME(dw, @FirstDateOfYear) AS Dayname 
UNION ALL 
SELECT cte.DayID + 1 AS DayID, 
DATEADD(d, 1 ,cte.FromDate), 
DATENAME(dw, DATEADD(d, 1 ,cte.FromDate)) AS Dayname 
FROM cte 
WHERE DATEADD(d,1,cte.FromDate) < @LastDateOfYear 
) 
SELECT FromDate AS Date, Dayname 
FROM CTE 
WHERE DayName LIKE 'Sunday' 
/* 
WHERE DayName IN ('Saturday,Sunday') -- For Weekend 
WHERE DayName NOT IN ('Saturday','Sunday') -- For Weekday 
WHERE DayName LIKE 'Monday' -- For Monday 
WHERE DayName LIKE 'Sunday' -- For Sunday 
*/ 
OPTION (MaxRecursion 370) 
+0

,但你能告诉我怎样才能打印第1周,第2周等多列... –

+1

这个解决方案依赖于具有英语语言设置的用户(其他文化会有不同的日期名称) –

+2

@ Kartik Patel WeekofYr = DATEPART(WEEK,FromDate)。即使我的查询也一样 –

0

尝试这样做是为了找到的第一个星期六:2012-01-01

    1. 开始。如果它不是一个周六,加上每天
    2. 转到2

    然后,在临时表中添加该日期和下一个日期(星期日)。 之后,循环执行以下操作:

    1. 7天和第8天添加到最后一个星期六你找到(你会得到如下周六和周日)
    2. 检查他们是否仍然在2012
    3. 如果他们,将它们存储在临时表中并转到1

    可能有更优雅的方式,但这是我的快速&肮脏的解决方案。由于您没有发布任何您尝试过的代码,因此我会将实施留给您。

  • 0

    你可以试试这个

    DECLARE @FirstDateOfYear DATETIME 
    SET @FirstDateOfYear = ’2010-01-01′ 
    SELECT DISTINCT DATEADD(d, number, @FirstDateOfYear), 
    CASE DATEPART(dw, DATEADD(d, number, @FirstDateOfYear)) 
    WHEN 7 THEN ‘Saturday’ 
    WHEN 1 THEN ‘Sunday’ 
    ELSE ‘Work Day’ 
    END 
    FROM master..spt_values 
    WHERE number BETWEEN 0 AND 364 
    AND (DATEPART(dw, DATEADD(d, number, @FirstDateOfYear)) = 1 OR DATEPART(dw, DATEADD(d, number, @FirstDateOfYear)) = 7) 
    ORDER BY DATEADD(d, number, @FirstDateOfYear) 
    
    3

    这样做是否有助于

    DECLARE @startDate DATETIME, @endDate DATETIME 
    SELECT @startDate = '2012-01-01', @endDate = '2012-12-31' 
    ;WITH Calender AS (
        SELECT @startDate AS dt 
        UNION ALL 
        SELECT dt + 1 FROM Calender 
        WHERE dt + 1 <= @endDate 
    ) 
    SELECT 
    dt 
    ,NameMonth = DATENAME(Month, dt) 
    ,NameDay = DATENAME (Weekday,dt) 
    ,WeekofYr = DATEPART(WEEK, dt) FROM Calender 
    WHERE DATENAME (Weekday,dt) IN ('Sunday') 
    Option(MaxRecursion 0) 
    

    的结果(部分)

    dt      NameMonth NameDay WeekofYr 
    2012-01-01 00:00:00.000 January  Sunday 1 
    2012-01-08 00:00:00.000 January  Sunday 2 
    ............................................... 
    ............................................... 
    2012-12-30 00:00:00.000 December Sunday 53  
    
    +0

    此解决方案*也*依赖于具有英语语言设置的用户(其他文化会有不同的日期名称) –

    0

    这也适用

    declare @dat datetime, @add int 
    
    set @dat = '20120101' 
    set @add = datepart(w,@dat) 
    
    set @add = 5 - @add -- friday 
    
    set @dat = dateadd(d,@add,@dat) 
    
    while @dat <= '20121231' 
    begin 
        print @dat 
        set @dat = dateadd(d,7,@dat) 
    end 
    
    0
    ;with AllDaysOfYear (Day) as (
        select DATEADD(year,DATEDIFF(year,0,CURRENT_TIMESTAMP),0) --Jan 1st 
        union all 
        select DATEADD(day,1,Day) from AllDaysOfYear 
        where DATEPART(year,DATEADD(day,1,Day)) = DATEPART(year,CURRENT_TIMESTAMP) 
    ) 
    select 
        ROW_NUMBER() OVER (ORDER BY Day) as WeekNo, 
        Day 
    from 
        AllDaysOfYear 
    where 
        DATEPART(weekday,Day) = DATEPART(weekday,'20120714') 
    option (maxrecursion 0) 
    

    首先,产生本年度(AllDaysInYear)一组的所有日子。然后,选择weekday是星期六的那些人。我使用的价值('20120714')不是非常重要 - 它必须是从任何一年的任何星期六。我只是用它来避免需要特别的DATEFIRST或语言设置。

    0

    此查询显示如何在第一部分中获得今年的第一天和下一年的第一天。下一年的第一天计算一次,以免不断收到并比较年份。

    ;WITH cte(TheDate,NextYear) AS 
    (
        SELECT CAST(CONVERT(CHAR(4),GETDATE(),112)+'0101' AS DATETIME), 
         CAST(YEAR(GETDATE())*10000+10101 AS CHAR(8)) 
        UNION ALL 
        SELECT DateAdd(d,1,TheDate),NextYear 
        FROM cte 
        WHERE DateAdd(d,1,TheDate)<NextYear 
    ) 
        SELECT Week = DatePart(wk,TheDate), 
         TheDate 
        FROM cte 
        WHERE DateName(dw,TheDate) in ('Saturday') 
    ORDER BY TheDate 
    OPTION (MAXRECURSION 366) 
    
    0
    with t as 
    (
    select 1 b 
    union all 
    select 1 b 
    union all 
    select 1 b 
    union all 
    select 1 b 
    union all 
    select 1 b 
    union all 
    select 1 b 
    union all 
    select 1 b 
    union all 
    select 1 b 
    ) 
    select * from 
    (
    select 
    current_timestamp 
    -datepart(dy,current_timestamp) 
    +row_number() over (order by t.b) d 
    from t, t t1, t t2 
    ) tmp 
    where datepart(yyyy,d)=datepart(yyyy,current_timestamp) 
         and 
         DATENAME(dw,d)='sunday' 
    
    相关问题