2012-09-19 167 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' 
    
    相關問題