将多个行和可变行移动到列

时间:2014-05-05 16:55:54

标签: sql-server

尝试将每个用户的多行移动到列。某些用户有不同的行数,例如,2或3封电子邮件,或1加电话号码。这取决于用户帐户。

看起来像这样。

Id  FirstName  LastName     Listing              phonetype   listingTypeID

1   Judy       Johnson      judyJ@email.com      null        4
1   Judy       Johnson      555-555-2020         home        2
1   Judy       Johnson      555-555-2022         home        2
1   Judy       Johnson      NULL                 null        1
2   Jim        Brown        555-555-3333         cell        2
2   Jim        Brown        jbrown@email.com     null        4
3   John       White        NULL                 null        1
3   John       White        johnwhite@email.com  null        4

空值表示地址,我想出了怎么做。我在stackflow上看过很多次这个例子,但不是每个用户可变行数。我意识到某些用户可能会使用某些列,但希望得到类似的内容。

Id  FirstName   LastName    email              email2             email3    phone           phone2        phone3

1   Judy        Johnson     judyJ@email.com                                 555-555-2020    555-555-2022    
2   Jim         Brown       jbrown@email.com   jbrown33@info.com            555-555-3333    555-555-2332    
3   John        White       jwhite@email.com                    

这就是我所拥有的并且它有效,但是当有多个具有相同类型的电子邮件或电话(即家庭或小区)时,没有创建新列。我正在考虑某种类型的If语句,但无法弄明白。

SELECT  id ,
        firstname ,
        lastname ,
        middlename ,
        prefix ,
        suffix ,
        notes ,
        MAX(line1) address ,
        MAX(line2) address2 ,
        MAX(city) city ,
        MAX(state) state ,
        MAX(zip) zip ,
        MAX(county) county ,
        MAX(country) country ,
        MAX(CASE WHEN phonetype = 'Cell' THEN listing END) Cell ,
        MAX(CASE WHEN phonetype = 'Home' THEN listing END) Home ,
        MAX(CASE WHEN phonetype = 'Office' THEN listing END) Office ,
        MAX(CASE WHEN phonetype = 'Fax' THEN listing END) Fax ,
        MAX(CASE WHEN listingTypeID = 4 THEN listing END) email ,
        MAX(CASE WHEN listingTypeID = 5 THEN listing END) weblink
FROM    [Matrix_Copy].[dbo].[Indiv]
GROUP BY id ,
        firstname ,
        lastname ,
        middlename ,
        prefix ,
        suffix ,
        notes
ORDER BY id

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

您可以使用PIVOT完全按照自己的意愿行事。诀窍是构建一个每个列表唯一的密钥。这可以使用ROW_NUMBER来完成,以确保如果用户有多个电话号码,它们将被标识为1,2,3等...将此值与ListingTypeId连接以获得[2-1],[ 2-2],[2-3]等,然后你基本完成了:

SELECT [Id], [Firstname], [Lastname], 
       [4-1] AS [Email], [4-2] AS [Email2],
       [2-1] AS [Phone], [2-2] AS [Phone2], [2-3] AS [Phone3]

FROM (
      SELECT *, 
        CAST(ListingTypeId AS NVARCHAR) + '-' + 
        CAST(ROW_NUMBER() OVER (PARTITION BY Id, ListingTypeId ORDER BY ListingTypeId) AS NVARCHAR) AS ListingTypeKey
      FROM
          [Matrix_Copy].[dbo].[Indiv]
      ) AS SourceTable
PIVOT (
    MAX(Listing)
    FOR ListingTypeKey IN ([4-1], [4-2], [2-1], [2-2], [2-3])
) AS PivotTable

现在,如果您想要返回两个以上的电子邮件地址或三个以上的电话号码,只需将它们添加到语句的SELECT部分​​的列表中,以及FOR ListingTypeKey IN中。电子邮件地址将编号为[4-1],[4-2],[4-3]等,而电话号码将编号为[2-1],[2-2],[2-3]等