【问题标题】:How to use two pivot如何使用两个枢轴
【发布时间】:2016-03-06 09:16:10
【问题描述】:

我有 3 张桌子:

1) 用户

 id    name
 1     abc
 1     abc
 2      tyu
 2      tyu

2) 电话

    id     number
     1     0987654
     1     0890764
     2     3445667
     2     5643456

3) 地址

id     addr  type
 1    usa    1
 1    uae    1 
 2    Uk     2

所以现在我写了下面的查询:

select * from (
              select u.id, u.name , p.number, cs.COL + CAST(row_number()over(PARTITION BY u.ID ORDER BY cs.COL) AS VARCHAR) RN ,
              cs1.COL + CAST(row_number()over(PARTITION BY a.ID ORDER BY cs1.COL) AS VARCHAR) RN1
               ,a.addr
              from user u left join phone p on p.id = u.id
              left join address as a on a.id = p.id CROSS APPLY (VALUES ('phone',number)) CS(Col,val)
                                                          CROSS APPLY (VALUES ('add',a.addr)) CS1(Col,val)
              where u.id=1 and a.type = '1'
              )P
    PIVOT (MAX(number) FOR RN IN ([phone1],[phone2])) as pivot1
    PIVOT (MAX(addr1)  FOR RN1 IN ([add1],[add2])) as pivot2

所以上面的查询给了我这样的输出:

id  name    phone1      phone2      add1        add2
1   abc     NULL        0987654     NULL       usa
1   abc     0890764      NULL       uae         NULL   

但我想要如下输出:

  id    name    phone1      phone2      add1        add2
    1   abc     0890764     0987654     uae         usa

那么我如何通过枢轴实现这一目标?

【问题讨论】:

  • 我拼凑了一些测试数据来试一试,但是当我运行您的查询时,我得到了无效的列名“IDnum”和无效的列名“addr1”。您能否更正您的帖子,以便您的示例查询与您的示例数据一致。
  • @BeanFrog 已更新。请看一下

标签: sql sql-server sql-server-2008 sql-server-2005 pivot


【解决方案1】:
declare @user TABLE 
    (id int, name varchar(3))
;    
INSERT INTO @user
    (id, name)
VALUES
    (1, 'abc'),
    (1, 'abc'),
    (2, 'tyu'),
    (2, 'tyu')
    ;
declare @phone  TABLE 
    (id int, number int)
;   
INSERT INTO @phone
    (id, number)
VALUES
    (1, 0987654),
    (1, 0890764),
    (2, 3445667),
    (2, 5643456)
;
declare @address TABLE 
    (id int, addr varchar(3), type int)
;  
INSERT INTO @address
    (id, addr, type)
VALUES
    (1, 'usa', 1),
    (1, 'uae', 1),
    (2, 'Uk', 2)
;

select id,name,MAX(phone1)phone1,max(phone2)phone2,max(add1)add1,max(add2)add2 from (
              select u.id, u.name , p.number, cs.COL + CAST(row_number()over(PARTITION BY u.ID ORDER BY cs.COL) AS VARCHAR) RN ,
              cs1.COL + CAST(row_number()over(PARTITION BY a.ID ORDER BY cs1.COL) AS VARCHAR) RN1
               ,a.addr
              from @user u left join @phone p on p.id = u.id
              left join @address as a on a.id = p.id CROSS APPLY (VALUES ('phone',number)) CS(Col,val)
                                                          CROSS APPLY (VALUES ('add',a.addr)) CS1(Col,val)
              where u.id=1 and a.type = '1'
              )P
    PIVOT (MAX(number) FOR RN IN ([phone1],[phone2])) as pivot1
    PIVOT (MAX(addr)  FOR RN1 IN ([add1],[add2])) as pivot2
    group by id,name

【讨论】:

  • @siddharth 你已经完成了所有的工作......只是我所采用的最大值
【解决方案2】:

在进行数据透视之前,您需要将数据转换为稍微不同的格式。 您的思路是正确的,但是将 RN 和 RN1 列合并为一个,然后同时对它们进行 pvioting 操作 - 如下所示。

select id, name, [phone1], [phone2], [add1], [add2]
from (
    select u.id, u.name, pa.columnname, pa.value from 
    user u inner join
    (
        select id, number as value, 'phone' + cast(row_number() over(partition by id order by number) as char(1)) as columnname
        from phone
        union all  
        select id, addr, 'add' + cast(row_number() over(partition by id order by addr) as char(1)) as columnname
        from address where type = 1
    ) as pa
        on pa.id = u.id
    ) as base
pivot (max(value) for columnname in ([phone1], [phone2], [add1], [add2])) p
where id = 1;

【讨论】:

    猜你喜欢
    • 2021-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-27
    相关资源
    最近更新 更多