带字符串的 TSQL 数据透视表

TSQL Pivot with strings

抱歉,据我所知,这个问题已在各种情况下得到多次回答。然而,经过一个小时的尝试并未能根据我的需要调整我发现的示例,我得出的结论是我是个白痴,需要针对我的数据的特定帮助...

我认为return的数据如下:

SELECT * 
FROM vwPersonMainContactDetails

输出:

PersonID  | ContactMethod   | ContactValue
----------+-----------------+-----------------
1           Email             Bob@abc.com
1           Mobile            07777 777777
2           Email             kate@abc.com
2           Mobile            07766 666666
3           Email             jo@abc.com
3           Mobile            07755 555555

我需要的是return数据结构如下:

PersonID  |  Mobile        |  Email
----------+----------------+--------------------------
1            07777 777777     bob@abc.com
2            07766 666666     kate@abc.com
3            07755 555555     jo@abc.com

有人可以帮忙吗?我知道 PIVOT 将是答案,但我真的很难让它为我工作...

非常感谢

安德鲁

如果您使用的是 SQL Server 2005+,您可以这样做:

SELECT
    *
FROM
(
SELECT
    PersonID,
    ContactMethod,
    ContactValue
FROM
    vwPersonMainContactDetails
) AS SourceTable
PIVOT
(
    MAX(ContactValue)
    FOR ContactMethod IN ([Email],[Mobile])
) AS pvt

如果您不使用 mssql,您可以这样做:

SELECT
    PersonID,
    MAX(CASE WHEN ContactMethod='Mobile' THEN ContactValue ELSE NULL END) AS Mobile,
    MAX(CASE WHEN ContactMethod='Email' THEN ContactValue ELSE NULL END) AS Email
FROM
    vwPersonMainContactDetails
GROUP BY
    PersonID

参考:

如果我们看一下 Pivot 的语法:

SELECT <non-pivoted column>,
    [first pivoted column] AS <column name>,
    [second pivoted column] AS <column name>,
    ...
    [last pivoted column] AS <column name>
FROM
    (<SELECT query that produces the data>)
    AS <alias for the source query>
PIVOT
(
    <aggregation function>(<column being aggregated>)
FOR
[<column that contains the values that will become column headers>]
    IN ( [first pivoted column], [second pivoted column],
    ... [last pivoted column])
) AS <alias for the pivot table>
<optional ORDER BY clause>;
  1. 本例中的聚合函数可以是:max/min
  2. 正在聚合的列:ContactValue = EmailMobile
  3. 现在在 Pivot 中,源 table 中剩余的所有列(此处为 T)都被考虑用于分组,在这种情况下它将是 PersonID,因此 Pivot 变为:

    SELECT PersonID, -- <non-pivoted column>, Mobile , --[first pivoted column] AS <column name>, Email--[second pivoted column] AS <column name>, FROM ( SELECT PersonID ,ContactValue,ContactMethod from vwPersonMainContactDetails)-- query that produces the data>) AS T --<alias for the source query> PIVOT ( max(ContactValue) --<aggregation function>(<column being aggregated>) FOR [ContactMethod] --<column that contains the values that will become column headers>] IN ( [Mobile],[Email]--[first pivoted column], [second pivoted column], ) )as pvt order by PersonID asc --<optional ORDER BY clause>; DEMO

提高可读性的另一种方式:

SELECT PersonID, [Email], [Mobile]
FROM [TABLE]
PIVOT (MAX(ContactValue) FOR ContactMethod IN ([Email], [Mobile])) AS PIV