MSSQL:使用动态值连接多个表

时间:2014-08-26 15:55:36

标签: sql-server join pivot entity-attribute-value

我很难将3个表放入一个查询中:

tPerson

ID          FirstName
1           'Jack'
2           'Liz'

tAttribute

ID          AttributeName
101         'LastName'
102         'Gender'

TDATA

PersonID    AttributeID     AttributeValue
1           101             'Nicholson'
1           102             'Male'
2           101             'Taylor'
2           102             'Female'

重要tAttribute中的属性是动态的。可能会有更多,例如:

ID          AttributeName
103         'Income'
104         'MostPopularMovie'

问题:如何编写查询(或查询是否有必要),以便我得到以下输出:

PersonID    FirstName   LastName        Gender      [otherFields]
1           'Jack'      'Nicholson'     'Male'      [otherValues]
2           'Liz'       'Taylor'        'Female'    [otherValues]

我经常阅读"到目前为止你尝试了什么?",但是使用子查询和连接发布我所有失败的尝试都没有多大意义。我对SQL不太安全。

非常感谢提前。

1 个答案:

答案 0 :(得分:0)

感谢@Tab Alleman,我谷歌搜索“SQL PIVOT”并得出以下结果:

SELECT      PersonID,
            FirstName,
            [LastName],
            [Gender]
FROM (
    SELECT      tPerson.ID AS PersonID,
                tPerson.FirstName,
                tAttribute.AttributeName,
                tData.AttributeValue
    FROM        tAttribute
    INNER JOIN  tData ON (
                    tAttribute.ID = tData.AttributeID
                )
    INNER JOIN  tPerson ON (
                    tData.PersonID = tPerson.ID
                )
) AS unPivotResult
PIVOT (
    MAX(AttributeValue)
    FOR AttributeName IN ([LastName],[Gender])
) AS pivotResult

添加:我不知道如何通过SQL动态获取LastNameGender,所以我使用ColdFusion,我用它进行编程。它看起来像这样:

<!--- "local.attributes" gets generated by making another query,--->
<!--- I just wrote it statically here for this example --->
<cfset local.attributes = "[LastName],[Gender]" />

<cfquery name="local.persons">
    SELECT      PersonID,
                FirstName,
                #local.attributes#
    FROM (
        ... 
    ) AS unPivotResult
    PIVOT (
        MAX(AttributeValue)
        FOR AttributeName IN (#local.attributes#)
    ) AS pivotResult
</cfquery>

如果我可以用类似的东西替换ColdFusion部分,那就太酷了 SELECT AttributeName FROM tAttribute然后使用它来获取括号定义。