2015-09-15 48 views
2

我有3個表:SQL服務器拼合數據

tUsers 
    -uid 

tColors 
    -colorid 
    -colorname 

tColors_User_Detail 
    -uid_fk 
    -colorid_fk 

用戶選擇自己喜歡哪種顏色,只有自己喜歡的顏色。這會在tColors_User_Detail中創建記錄。我需要將其平滑化,以便每個用戶都有一個記錄,其中tColors的顏色作爲列名稱,並且每行顏色的行中都有True/False值,具體取決於它們是否在tColors_User_Detail中有記錄。如果用戶沒有在tColors_User_Detail中選擇一種顏色,則它將是特定顏色列中的False值。而且,如果他們確實在tColors_User_Detail中有一個顏色記錄,則對於相應的顏色列將是一個真實值。

任何幫助表示讚賞。

+1

你能提供你已經嘗試過的嗎? – Dane

+2

還可以用很少的行對輸入和輸出數據進行採樣以解釋所需的輸出。 – Utsav

+0

Google是PIVOT運營商,或者其他的主要解決方案。這些旨在做你想做的。 –

回答

2

下面是一個基本的PIVOT示例,如果沒有可用的值,則COALESCE顯示'false'。這假定你必須硬編碼列名的顏色名稱。

DECLARE @tUsers TABLE ([uid] INT) 
DECLARE @tColors TABLE ([colorid] INT, [colorname] VARCHAR(50)) 
DECLARE @tColors_User_Detail TABLE ([uid_fk] INT, [colorid_fk] INT) 
INSERT @tUsers VALUES (1),(2) 
INSERT @tColors VALUES (1,'Blue'),(2,'Red'),(3,'Green') 
INSERT @tColors_User_Detail VALUES (1,1),(1,2),(1,3),(2,1) 

SELECT 
    uid, 
    COALESCE([Red], 'False') AS [Red], 
    COALESCE([Blue], 'False') AS [Blue], 
    COALESCE([Green], 'False') AS [Green] 
FROM @tUsers U 
    LEFT OUTER JOIN @tColors_User_Detail CUD 
     ON CUD.uid_fk = U.uid 
    LEFT OUTER JOIN @tColors C 
     ON C.colorid = CUD.colorid_fk 
    PIVOT (MAX(colorname) FOR colorname IN (
     [Red], 
     [Blue], 
     [Green] 
    )) PVT 

如果你想讓顏色動態的列,你必須使用動態SQL。

DECLARE @Sql VARCHAR(1000) = 
    'SELECT uid' 
    + (SELECT ', CASE WHEN [' + [colorname] + '] IS NOT NULL THEN ''True'' ELSE ''False'' END AS [' + [colorname] + ']' AS [text()] FROM tColors FOR XML PATH('')) 
    + ' FROM tUsers U 
      LEFT OUTER JOIN tColors_User_Detail CUD 
       ON CUD.uid_fk = U.uid 
      LEFT OUTER JOIN tColors C 
       ON C.colorid = CUD.colorid_fk 
      PIVOT (MAX(colorname) FOR colorname IN (' 
    + SUBSTRING((SELECT ',[' + [colorname] + ']' AS [text()] FROM tColors FOR XML PATH('')), 2, 1000) 
    + ')) PVT' 
EXEC (@Sql) 
+0

謝謝。是的,我需要從tColors表中拉出顏色名稱,而不是硬編碼,因爲可用顏色可能會隨時間而改變。 – devnuts

+0

剛剛更新了動態sql。 –

+0

謝謝,我會看看我能用這個做什麼。 – devnuts

1

什麼味道的SQL?

東西線沿線的: http://sqlfiddle.com/#!6/ec4e2

SELECT U.uid 
    , C.colorid 
    , C.colorname 
    , (CASE WHEN cud.uid_fk IS NOT NULL THEN 'True' ELSE 'False' END) AS ColorChosen 
FROM tUsers U 
FULL OUTER JOIN tColors C ON 1=1 
LEFT OUTER JOIN tColors_User_Detail cud ON 
    U.uid = cud.uid_fk 
    AND C.colorid = cud.colorID_FK 

編輯:我錯過了支點爲每個用戶一行。雖然會議時間。稍微回來一下。