如何使用两个枢轴

时间:2015-12-02 07:59:03

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

我有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

那么我怎样才能通过支点实现这一目标?

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

在转动之前,您需要将数据放入稍微不同的格式。 你是沿着正确的线,但是将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;