2011-06-07 163 views
2

我有一排數據,開始日期和結束日期通常是從月初到月底。然而,有時行有 - 幾個月長 - 在一個月的中間開始,結束在同一個月或未來的月份 - 開始於一個月的開始,但結束某處在一個月的中間未來一個月。按月分解日期範圍

我需要按月分解這些日期範圍,但不知道如何去做這件事。

任何指導表示讚賞。

感謝,

+0

因此,如果開始日期和結束日期是在兩個不同的月份,你怎麼想代表這個?兩個不同的值,每個月一個?只是開始日期?只是結束日期?這兩個日期的平均值? – 2011-06-07 18:58:44

+0

我需要通過各自的一個月,以保持每個單獨的,所以如果例如它是6月13日至7月18日,那麼它應該是 6月13日至6月30日 七月1日至7月18日 例如 – mohsen 2011-06-07 19:16:52

+0

你的問題太錨定在你的上下文中對其他人都有用。它也很模糊。請更改它並提供有關您正在使用的工具,已嘗試的內容,示例輸入數據和所需輸出數據的信息。 – 2011-06-07 21:35:36

回答

1

一個標準關鍵是要建立一個months表,然後選擇所有月份相交的日期範圍。

您可以再往前走一步,並在您的選擇中使用CASE聲明,以便您獲取月份的開始日期,該月份是所提供的開始日期和月份的開始日期的最大值,以及結束日期月份是所提供的最低月份和月末的最低月份。

這將讓你採取單一的日期範圍,並獲得一組日期範圍。然後,您可以將該查詢加入到您月份的數據集和組中,以便在一個月的範圍內按月對數據進行分割。 (這個技巧在某些時段可能沒有數據時特別有用,但您希望它們顯示,只需使用左連接。)

2

您可以使用數字表執行此任務。

在下面稱爲master..spt_values系統表的示例查詢被用作數表的替換:

SELECT 
    CASE WHEN BeginDate > MonthStart THEN BeginDate ELSE MonthStart END AS BeginDate, 
    CASE WHEN EndDate < MonthEnd THEN EndDate ELSE MonthEnd END AS EndDate, 
    … /* other columns as needed */ 
FROM (
    SELECT 
    d.*, /* or you could be more specific here */ 
    (
     DATEADD(month, DATEDIFF(month, 0, d.BeginDate) + v.number, 0) 
    ) AS MonthStart, 
    DATEADD(day, -1, 
     DATEADD(month, DATEDIFF(month, 0, d.BeginDate) + v.number + 1, 0) 
    ) AS MonthEnd 
    FROM RowsOfData d 
    INNER JOIN master..spt_values v ON v.type = 'P' 
     AND v.number BETWEEN 0 AND DATEDIFF(month, d.BeginDate, d.EndDate) 
) s 

每一行都被劃分成一系列的行,其中BeginDate或者是實際BeginDate或開始取決於哪個值更大,同樣適用於EndDate。爲了說明,以下行

BeginDate EndDate 
---------- ---------- 
2010-03-05 2010-03-24 
2010-04-16 2010-05-05 
2010-06-29 2006-08-12 
2010-10-10 2011-02-01 

將拆分這樣的:

BeginDate EndDate 
---------- ---------- 
2010-03-05 2010-03-24 
2010-04-16 2010-04-30 
2010-05-01 2010-05-05 
2010-06-29 2010-06-30 
2010-07-01 2010-07-31 
2010-08-01 2010-08-12 
2010-10-10 2010-10-31 
2010-11-01 2010-11-30 
2010-12-01 2010-12-31 
2011-01-01 2011-01-31 
2011-02-01 2011-02-02 
+0

+1爲「數字」或順序方法。 – pilcrow 2011-06-08 16:54:29