2017-04-25 71 views
0

我設計了一個EAV表看起來像這樣:SQL中使用PIVOT多值屬性

SID AID VID 
1  1 1 
1  2 1 
1  3 2 
1  4 3 
1  1 2 

SID代表對象ID,AID代表屬性ID和VID代表ValuedID

還表到屬性映射:

AttributeID AttributeName 
    1   Hobbies 
    2   Name 
    3   Gender 
    4   IrisColor 

使用在所述第一表樞軸之後,鏈接到屬性表:

SELECT 
    SubjectID, 
    Hobbies, 
    Name, 
    Gender, 
    IrisColor  
FROM 
(
SELECT SubjectID, attr.AttributeName as attribute, ValueID from SubjectDetails, SubjectAttributes as attr WHERE SubjectDetails.AttributeID=attr.ID 
) as t 
PIVOT(
MAX(ValueID) 

FOR attribute IN (Hobbies,Name,Gender,IrisColor)) AS t1 

WHERE SubjectID=1 

我得到這個:

SubjectID Hobbies Name Gender IrisColor 
    1  1  1  2  3 

這幾乎是正確的,但SubjectAttribute 1(這是愛好)出現更多的時間在第一個表(SubjectDetails),所以我想實現的是:

SubjectID Hobbies Name Gender IrisColor 
    1  **1,2**  1  2  3 

我不得不提,我不關心使用的分隔符是什麼,並且我想這樣做,用那東西的功能,但它是一個痛苦的PIVOT和東西結合起來(或者我只是不知道如何)..任何建議?

+0

您可以通過修改源EAV表,使其具有每個屬性一行用逗號分隔值,然後轉動使用您的數據透視查詢。 –

+0

我不能這樣做..需求是爲每個屬性分開行,即使它重複。我只是不想在視圖中這樣做,但不能用逗號分隔存儲它 – berthos

回答

1

這應該工作,我做了以下內容: 存儲的信息從您的EAV表(table1)按SID單列爲temporary table(你可以創建一個view代替)。 然後轉動該結果集如下(使用數據透視查詢):

SELECT * 
FROM 
    (
    SELECT * from #temptbl 
) as t 
PIVOT(MAX(vid) FOR attrname IN (Hobbies,Name,Gender,IrisColor)) AS t1 
WHERE sid=1 

我得到了這樣的結果:

enter image description here

請檢查完整的工作版本here

+0

它的工作原理!謝謝! – berthos

+0

非常好! :)快樂編碼! –

+0

還有一個問題,最佳方式是什麼,每次創建一個視圖或重新創建表格? – berthos

0

這將不使用PIVOT工作,我覺得這裏沒有必要使用PIVOT

SELECT SubjectID 
     ,+STUFF((SELECT ', '+CAST(ValueID AS NVARCHAR) 
       FROM @T_SubjectAttributes A 
       INNER JOIN @T_SubjectDetails B ON A.AttributeID = B.AttributeId 
       WHERE AttributeName = 'Hobbies' 
       AND B.SubjectID = H.SubjectID FOR XML PATH('')) 
         ,1,2,'') AS Hobbies 
     ,STUFF((SELECT ', '+CAST(ValueID AS NVARCHAR) 
       FROM @T_SubjectAttributes A 
       INNER JOIN @T_SubjectDetails B ON A.AttributeID = B.AttributeId 
       WHERE AttributeName = 'Name' 
       AND B.SubjectID = H.SubjectID FOR XML PATH('')) 
         ,1,2,'') AS Name 
     ,STUFF((SELECT ', '+CAST(ValueID AS NVARCHAR) 
       FROM @T_SubjectAttributes A 
       INNER JOIN @T_SubjectDetails B ON A.AttributeID = B.AttributeId 
       WHERE AttributeName = 'Gender' 
       AND B.SubjectID = H.SubjectID FOR XML PATH('')) 
         ,1,2,'') AS Gender 
     ,STUFF((SELECT ', '+CAST(ValueID AS NVARCHAR) 
       FROM @T_SubjectAttributes A 
       INNER JOIN @T_SubjectDetails B ON A.AttributeID = B.AttributeId 
       WHERE AttributeName = 'IrisColor' 
       AND B.SubjectID = H.SubjectID FOR XML PATH('')) 
         ,1,2,'') AS IrisColor 
FROM @T_SubjectDetails H 
GROUP BY SubjectID