2009-05-27 164 views
4

我有一個日期範圍,開始日期是今天之前的2年。例如'05/29/2007'〜'05/29/2009'。按周分組日期範圍

我該如何突破日期範圍,以便獲得如下列表?

(開始日期從「05/27/2007」開始,而不是「05/29/2007」,因爲從星期一開始是星期天,'05/27/2007'是'05 /二千〇七分之二十九' 和同樣的道理在過去的結束日期,二○○九年五月三十○日,這是星期六)

StartDate EndDate 
05/27/2007 06/02/2007 
06/03/2007 06/09/2007 
... 
05/24/2009 05/30/2009 

[更新]這裏是我的最終查詢

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 num, lvl, 
    DATEADD(dw, -DATEPART(dw, '2007-05-29'), '2007-05-29') + num * 7, 
    DATEADD(dw, -DATEPART(dw, '2007-05-29'), '2007-05-29') + (num + 1) * 7 
FROM hier 
where num <= 104 --; 52 weeks/year * 2 
ORDER BY num 
+0

感謝您發佈最新結果的更新。大多數人沒有意識到它對其他人有多大的幫助。 – Crimius 2012-08-16 12:44:35

回答

4
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 DATEADD(dw, -DATEPART(dw, '29.05.2007'), '29.05.2007') + num * 7, 
     DATEADD(dw, -DATEPART(dw, '29.05.2007'), '29.05.2007') + (num + 1) * 7 
FROM hier 
WHERE DATEADD(dw, -DATEPART(dw, '29.05.2007'), '29.05.2007') + num * 7 < '29.05.2009' 
ORDER BY 
     num 

這將產生你所需要的範圍內的行集。

+0

@Quassnoi:與CTE的偉大的遞歸的東西。讓我試着在我的查詢中使用它。 – Sung 2009-05-27 16:17:03

2

您需要確保@@ DATEFIRST已正確發送,那麼您可以簡單地使用下面的代碼。儘管如此,請閱讀DATEFIRST,以便完全理解它。

SET DATEFIRST 1 

DECLARE @my_date DATETIME 

SET @my_date = '2007-05-29' 

SELECT 
    DATEADD(dw, -DATEPART(dw, @my_date), @my_date) AS StartDate, 
    DATEADD(dw, 6 - DATEPART(dw, @my_date), @my_date) AS EndDate 
+0

我想弄清楚我需要從查詢中提取出什麼「變量」。讓我看看... – Sung 2009-05-27 16:03:51

+0

我使用@my_date只是爲了讓它在沒有表格的情況下運行。那將是您在2007年5月29日提供的專欄或變量。如果您將其從當前日期中刪除,則只需設置一個變量並使用它即可。看着Quassnoi的它看起來也許你想要一組日期範圍而不是一個單一的日期範圍,所以這可能不完全回答你的問題。您可以加入數字表格或日曆表格,以根據需要擴展它,或者像Quassnoi所做的CTE一樣。 – 2009-05-27 16:21:40

0

應該在你的SQL語句非常簡單directy ......我已經處理日期和日期計算的一個很長的歷史,所以我想辦法是這樣的:

select 
     datepart(year, YourDateField) as GroupYear, 
     datepart(week, (YourDateField - datepart(day, YourDateField) +1) as GroupWeek, 
     YourDateField, 
     OtherFields 
    from 
     YourTable 
    where 
     whateverDateRange... 
    group by 
    GroupYear, 
    GroupWeek 

的原因一年一週是如果你跨越多年,你會有第一年的第2周前兩年的第1周,等等。

現在,數學如何工作...爲GroupWeek。這實際上會根據您的數據的任何日期爲基礎計算一週中的第一天......假設您有今年5月25日,26日和27日的數據......他們分別是第2,3,4天星期日開始於第1天的星期。因此:

5月25日 - 2日(星期幾)= 5月23日(星期六)+1 = 5月24日(星期日)。 5月26日至3日(星期)= 5月23日......等 5月27日至4日(星期)= 5月23日

因此,通過還包括有問題的原日期字段,你可以看到真正的日期全部在一個SQL調用中...