SQL将PIVOT用于多值属性

时间:2017-04-25 06:03:27

标签: sql-server database pivot rows multivalue

我设计了一个如下所示的EAV表:

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

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

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

我必须提一下,我不关心使用什么分隔符,而且我尝试使用STUFF函数,但结合PIVOT和STUFF是困难的(或者我只是不知道如何)。有什么建议吗?

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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