2009-06-24 91 views
3

我有一張表,其中包含兩列,一列用於開始日期,另一列用於結束日期。我需要編寫一個查詢,該查詢將爲每年的每個月返回一列,如果月份在0之內,那麼該列的值爲1。 PIVOT聲明似乎是我在這裏尋找的內容,但從最好的角度來看,我可以告訴PIVOT子句正在尋找匹配值,而不是檢查值是否在兩個其他值之間。在這裏,PIVOT條款是正確的結構,還是我需要分解並編寫12個案例陳述,然後彙總這些陳述​​?基於兩列之間的值的SQL數據透視表

回答

2

我想我已經在這裏得到了解決方案。有3個基本步驟:

  1. 獲取的日期在每12個月
  2. 檢查,如果這個日期開始和結束日期之間
  3. PIVOT結果

要獲得12個日期,每個月一個,我用一個像WITH語句的小遞歸來創建一個包含12個日期的1列的臨時表:

WITH months (date) AS (
SELECT GETDATE() AS date 
UNION ALL 
SELECT 
    DATEADD(MONTH,1,date) 
FROM months 
WHERE DATEDIFF(MONTH,GETDATE(),date) < 12) 

從這裏我可以CROSS JOIN這張臨時表與我真正關心的信息。然後我使用開始和結束之間的WHERE日期來濾除不屬於那個月的任何條目。因此,像這樣:

SELECT other.Title, MONTH(months.date) CROSS JOIN other 
WHERE months.date BETWEEN other.start AND other.end 

在這一步,我們必須謹慎,只選擇我們的結果明確地渴望列,或者那些將使用PIVOT語句彙總。

最後,我們必須轉動的結果:

PIVOT (MAX(PID) FOR date IN ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12])) 

因此產生的查詢可能看起來像:

WITH months (date) AS (
SELECT GETDATE() AS date 
UNION ALL 
SELECT 
DATEADD(MONTH,1,date) 
FROM months 
WHERE DATEDIFF(MONTH,GETDATE(),date) < 12) 
SELECT Title, 
    [1]  AS January, 
    [2]  AS February, 
    [3]  AS March, 
    [4]  AS April, 
    [5]  AS May, 
    [6]  AS June, 
    [7]  AS July, 
    [8]  AS August, 
    [9]  AS September, 
    [10] AS October, 
    [11] AS November, 
    [12] AS December 
FROM 
(
SELECT other.Title,MONTH(months.date) 
CROSS JOIN other 
WHERE months.date BETWEEN other.startDate AND other.endDate 
) AS subquery 
PIVOT (MAX(PID) FOR date IN 
([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12])) AS p 

我已經去掉了所有的其他複雜的我經歷了加盟在我需要的其他信息中,所以這實際上並不是我寫的查詢,但它應該封裝我用來根據需要獲取結果的基本查詢結構。

0

我會去12個案例的陳述。

這實際上是我在回去之前勾畫出的解決方案,並且看到您在其中提到了您的問題。

0

爲什麼不計算月份的列,然後用它來轉折?

日期部分(月,[日])

還是我誤解了問題?