2010-12-10 25 views
1

我有一張表格,裏面有這樣的列表SubjectID UserID。單個用戶有很多subjectIDs。我需要做某些選擇以獲得類似於此的結果集:從平坦表格中選擇

UserID1 SubjectID1 SubjectID2 Subject3 
UserID2 SubjectID1 SubjectID2 Subject3 
UserID3 SubjectID1 SubjectID2 Subject3 
+0

@ p.campbell,我懷疑他與他的第一句話.. – 2010-12-10 22:13:20

回答

1

爲便於討論,讓我們定義一個表中的樣本數據集名爲SubjectUser如下:

;WITH 
    orderedSubjects AS (
    SELECT 
     UserId 
    , SubjectId 
    , 'SubjectId' 
     + CAST(
      ROW_NUMBER() OVER (PARTITION BY UserId ORDER BY SubjectId) 
      AS NVARCHAR) 
     AS col 
    FROM SubjectUser 
) 
SELECT * 
FROM orderedSubjects 
PIVOT (
    MAX(SubjectId) 
    FOR col IN (SubjectId1, SubjectId2, SubjectId3) 
) AS p 

SELECT NULL AS SubjectId, NULL AS UserID INTO SubjectUser WHERE 1=0 
UNION SELECT 'cpsc500', 'maxt3r' 
UNION SELECT 'phil507', 'zontar33' 
UNION SELECT 'phil507', 'maxt3r' 
UNION SELECT 'eng501', 'zontar33' 
UNION SELECT 'eng501', 'maxt3r' 
UNION SELECT 'bkwv101', 'spaced99' 

然後,您可以使用此查詢得到期望的結果

讓我們看看這個查詢的部分。第一個問題是爲每個用戶的主題分配列名。 BY來分配序列號到每個用戶的科目

SELECT 
    UserId 
, SubjectId 
, 'SubjectId' 
    + CAST(
     ROW_NUMBER() OVER (PARTITION BY UserId ORDER BY SubjectId) 
     AS NVARCHAR) 
    AS col 
FROM SubjectUser 

ROW_NUMBER()... PARTITION BY ...順序:orderedSubjects表用於此目的,此查詢定義。任意地,主題按字母順序排列。然後,通過在每個序列號前加上字符串SubjectId來生成列名稱。結果如下:

UserId  SubjectId col 
maxt3r  cpsc500  SubjectId1 
maxt3r  eng501  SubjectId2 
maxt3r  phil507  SubjectId3 
spaced99 bkwv101  SubjectId1 
zontar33 eng501  SubjectId1 
zontar33 phil507  SubjectId2 

我們現在有我們需要的數據來創建最終結果。它是由樞轉orderedSubjects獲得:

SELECT * 
FROM orderedSubjects 
PIVOT (
    MAX(SubjectId) 
    FOR col IN (SubjectId1, SubjectId2, SubjectId3) 
) AS p 

MAX的應用是必要的,只是因爲PIVOT語法需要使用聚合功能的。在這種情況下,每個組中只有一個SubjectID,所以MAX可能就像MIN一樣容易。

另請注意,SQL Server PIVOT語法要求生成的數據透視列集的數量是固定的。在這種情況下,查詢是三個主題的硬編碼。如果數據包含的值超過分配的列數,則會丟棄超出部分。

最終的結果如下:

UserId  SubjectId1  SubjectId2  SubjectId3 
maxt3r  cpsc500   eng501   phil507 
spaced99 bkwv101   NULL   NULL 
zontar33 eng501   phil507   NULL 
2

您正在使用哪個數據庫? Microsoft SQL Server(2005年以後)有PIVOT/UNPIVOT將行轉換爲列,反之亦然。 http://msdn.microsoft.com/en-us/library/ms177410.aspx

+0

我猜PIVOT正是我需要的。你能給我一個示例查詢嗎? – 2010-12-10 22:16:53

+0

不靠近有真正的筆記本電腦上的sql服務器。 Pinal Dave已經在這裏博客了http://blog.sqlauthority.com/2008/06/07/sql-server-pivot-and-unpivot-table-examples/以及我上面給出的BOL鏈接也有例子 – Ash 2010-12-10 23:26:12

+0

您可能需要考慮編輯您的答案以包含來自您評論的鏈接。 – 2010-12-11 06:10:04