【问题标题】:SQL Pivot with String带字符串的 SQL 透视图
【发布时间】:2012-04-25 16:12:19
【问题描述】:

我在 SQL Server 中有两个表:Customer 和 Address

客户表

CustomerID  FirstName  LastName
----------- ---------- ----------
1           Andrew     Jackson         
2           George     Washington

地址表

AddressID   CustomerID  AddressType City
----------- ----------- ----------- ----------
1           1           Home        Waxhaw     
2           1           Office      Nashville    
3           2           Home        Philadelphia

这是我需要的输出:

CustomerID  Firstname  HomeCity      OfficeCity
----------- ---------- ----------    ----------
1           Andrew     Waxhaw        Nashville
2           George     Philadelphia  Null

这是我的查询,但没有得到正确的结果:

SELECT CustomerID, Firstname, HOme as HomeCity, Office as OfficeCity FROM 
   (SELECT C.CustomerID, C.FirstName, A.AddressID, A.AddressType, A.City 
    FROM Customer C, Address A 
    WHERE C.CustomerID = A.CustomerID)as P
PIVOT (MAX(city) FOR AddressType in ([Home],[Office])) as  PVT

这是我得到的结果:

CustomerID  Firstname  HomeCity      OfficeCity
----------- ---------- ----------    ----------
1           Andrew     Waxhaw        NULL
1           Andrew     NULL          Nashville
2           George     Philadelphia  Null

如您所见,客户 1 在最终结果中出现了两次。是否有可能每个客户只能获得一行?

我查了这个例子,但没有帮助:http://stackoverflow.com/questions/6267660/sql-query-to-convert-rows-into-columns

谢谢

【问题讨论】:

    标签: sql pivot


    【解决方案1】:

    之所以给出这一行,是因为您在子查询“P”的选择列表中有AddressID。因此,即使您在顶层没有 AddressID 选择这个,PIVOT 函数仍然按它分组。您需要将其更改为:

    SELECT  CustomerID, Firstname, Home as HomeCity, Office as OfficeCity 
    FROM    (   SELECT C.CustomerID, C.FirstName, A.AddressType, A.City 
                FROM #Customer C, #Address A 
                WHERE C.CustomerID = A.CustomerID
            ) AS P
            PIVOT 
            (   MAX(city) 
                FOR AddressType in ([Home],[Office])
            ) AS  PVT
    

    虽然我倾向于使用显式的INNER JOIN,而不是客户和地址之间的隐式连接。

    【讨论】:

    • 太棒了,成功了!谢谢!!我没有意识到 addressID 是造成它的原因。我习惯了隐式连接,但我将开始使用你提到的 INNER JOIN。
    • 在这种情况下,使用隐式连接还是内部连接并没有太大区别,并且有许多关于该主题的不同讨论,例如here。我个人的观点是显式连接更易于阅读,允许在“内部”和“外部”连接之间更轻松地进行更改,并且还可以通过缺少 where 子句来减少意外交叉连接的可能性。
    【解决方案2】:

    我会这样写:

    SELECT C.CustomerID, C.Firstname,
        Home.City as HomeCity,
        Office.City as OfficeCity
    FROM Customer C
        LEFT JOIN Address Home
            on Home.CustomerID = C.CustomerID and Home.AddressType = 'Home'
        LEFT JOIN Address Office
            on Office.CustomerID = C.CustomerID and Office.AddressType = 'Office'
    

    【讨论】:

    • 谢谢,这看起来是另一种不使用 PIVOT 的好方法。
    • 如果您不需要聚合任何内容,这很有效。我有一个表,其中包含一些我取消透视、规范化的字符串列,然后用它来重建
    猜你喜欢
    • 1970-01-01
    • 2018-10-05
    • 2019-05-14
    • 2010-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-23
    • 1970-01-01
    相关资源
    最近更新 更多