2011-12-01 74 views
1

我有一個問題作出查詢。SQL Server查詢:行使列(透視?)

此查詢,我創建

WITH TATH(Priority, EntryDate) AS 
(
    SELECT TH.Priority as Priority, DATEADD(dd, 0, DATEDIFF(dd, 0, entryDate)) as EntryDate 
     FROM TicketAssignment TA, TicketHeader TH 
    WHERE TA.TicketID = TH.TicketID 
     AND TA.Company = 'IT' 
     AND TA.CurrentRole IN ('SA1B','SA1C','SDA') 
) 
SELECT Priority, convert(varchar(10), EntryDate,103) as EntryDate, COUNT(*) AS Count 
FROM TATH 
GROUP BY Priority, EntryDate 

,到目前爲止,其結果是:

Priority EntryDate Count 
0 25/11/2011 1 
1 25/11/2011 2 
2 25/11/2011 36 
3 25/11/2011 8 
0 28/11/2011 3 
1 28/11/2011 3 
2 28/11/2011 37 
3 28/11/2011 37 

我想要的結果看起來是這樣

EntryDate Priorty0 Priority1 Priority2 Priority3 
25/11/2011 1 2 36 8 
28/11/2011 3 3 37 37 

我認爲這是出於我的能力,我尋找樞軸,但我無法實現。

如果一個關鍵點不是一個好的解決方案,我必須搜索(或研究)什麼?

你能幫我嗎Q.Q?

+0

從你的文章來看,實際上你並沒有很清楚你到底嘗試了什麼。你只是試圖找出[內置支持在SQL Server中的pivoting](http://msdn.microsoft.com/en-us/library/ms177410.aspx)?還是儘量努力掌握如何使用它?或者你已經嘗試過這個功能?請看看這個主題的*相關*部分。它包含許多關於在SQL Server中進行pivoting的問題(還有例子)。在另一個說明中,不清楚在結果查詢中是否應該修復Priority列的數量。 –

+0

@AndriyM我讀了MSDN頁後嘗試了Pivot。我無法實現它。當我試過Count不適合。我的問題是... DISTINCT(Entry date和Priority)行進入列,Count列進入行。對不起我的英語不好。 – ShootingStar

+0

因此,我明白,您對PIVOT有困難。關於我的另一個問題,關於優先級列的問題呢?在輸出*中總是應該有正好四個優先級列*,例如(Priorty0,Priority1,Priority2,Priority3)。 –

回答

2

旋轉就像分組一樣。您可以將其視爲有限的分組,並帶有「特殊效果」。限制在於只能有一個聚合列。 (在正常的GROUP BY查詢中,你可以自然地有多個)。當然,我的意思是「特殊效果」,其他列中的一個(並且只有一個)被轉換爲多個列。

讓我們以您的GROUP BY查詢爲例。輸出中有三列。其中之一Count是包含彙總信息的列。這是分散在PIVOT查詢中的多個列中的一個。另一列Priority是結果按其他兩列分組的結果之一,也是需要進行旋轉的列。最後,EntryDate是另一個GROUP BY列。它應該保持原樣,因爲它不直接參與旋轉。

現在讓我們怎麼你的主要選擇會從通常GROUP轉化BY查詢看透一個PIVOT查詢,分步實施:

  1. 由於分組的PIVOT查詢暗示,GROUP BY子句被刪除。相反,引入了PIVOT條款。

  2. Count列的表達式從SELECT子句移動到PIVOT子句。

  3. Priority列的拆分在PIVOT子句中定義。

  4. SELECT子句中的PriorityCount列由PIVOT子句中定義的列的列表替換。

  5. EntryDate列在SELECT子句中保持不變。

而這裏的結果查詢,有意見標誌着上述轉型的每一個部分:

WITH TATH(Priority, EntryDate) AS 
(
    SELECT TH.Priority as Priority, DATEADD(dd, 0, DATEDIFF(dd, 0, entryDate)) as EntryDate 
     FROM TicketAssignment TA, TicketHeader TH 
    WHERE TA.TicketID = TH.TicketID 
     AND TA.Company = 'IT' 
     AND TA.CurrentRole IN ('SA1B','SA1C','SDA') 
) 
SELECT 
    convert(varchar(10), EntryDate,103) as EntryDate,      -- #5 
    [0] AS Priority0, [1] AS Priority1, [2] AS Priority2, [3] AS Priority3 -- #4 
FROM TATH 
PIVOT (                 -- #1 
    COUNT(*)                -- #2 
    FOR Priority IN ([0], [1], [2], [3])         -- #3 
) p 

/* -- your original main query, for comparison 
SELECT 
    Priority,                -- #4 
    convert(varchar(10),             -- #5 
    EntryDate,103) as EntryDate, COUNT(*) AS Count       -- ##2&4 
FROM TATH 
GROUP BY Priority, EntryDate            -- #1 
*/ 

還有的PIVOT子句中的列列表上的一個附加的註釋。首先,你必須理解,根據列的數量和它們的名字,得到的一組SQL查詢應該是固定的*。這意味着您必須明確枚舉要在輸出中看到的所有轉換列。這些名稱來源於正在旋轉的列的值,但應將其指定爲名稱,而不是值。這就是爲什麼你可以在列出的數字周圍看到方括號。由於號碼本身不符合rules for regular identifiers,它們必須被分隔。

您還可以看到,您可以像SELECT任何其他列或表達式那樣在SELECT子句中別名旋轉列。因此,最後,您不必以無意義的0,1等標識符結束,而是可以將這些列分配您喜歡的任何名稱。


*如果你想被轉動的列數和/或名稱是動態的,你就必須動態地構建查詢,即先收集的名稱,然後將它們合併成一個包含查詢其餘部分的字符串,並用EXEC()EXEC sp_executesql調用最終查詢。有關動態旋轉的更多信息,您可以登錄search this site

+0

非常感謝。我無法用英語表達多少Q.Q – ShootingStar