SQL 对多值属性使用 PIVOT

SQL Using PIVOT for multi valued attributes

我设计了一个 EAV table,看起来像这样:

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

SID代表Subject ID,AID代表Attribute ID,VID代表ValuedID

还有一个table来映射属性:

AttributeID AttributeName
    1            Hobbies
    2            Name
    3            Gender
    4            IrisColor

在第一个 table 上使用 pivot 后,链接到属性 table:

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(即爱好)在第一个table(SubjectDetails)中出现了一次,所以我想要实现的是:

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

我不得不提一下,我不关心使用什么分隔符,我尝试使用 STUFF 函数来做到这一点,但是将 PIVOT 和 STUFF 结合起来很痛苦(或者我只是不知道如何) ..有什么建议吗?

这应该可行,我做了以下操作: 将来自您的 EAV table (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

我得到了这个结果:

请检查完整的工作版本here

这个不用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