在tsql中使用pivot

时间:2016-08-23 05:29:33

标签: sql sql-server tsql

假设我有这张表:

Name        Occupation
Samantha    Doctor
Julia       Actor
Maria       Actor
Meera       Singer
Ashely      Professor
Ketty       Professor
Christeen   Professor
Jane        Actor
Jenny       Doctor
Priya       Singer

我想要输出:

    Doctor     Professor    Singer   Actor
    Jenny       Ashley      Meera    Jane
    Samantha    Christeen   Priya    Julia
    NULL        Ketty       NULL     Maria

我想将占用行转换为列,然后按占用列出名称。 我一直在尝试pivot关系运算符,但我们传递给pivot的第一个参数应该是一个聚合函数,所以我不确定这是否是解决此查询的最佳方法。 这是我一直在使用pivot工作的查询,但当然我正在使用max(name)它只返回一个名称:

select * from occupations 
pivot (max(name) for occupation in ([doctor],[actor],[singer],[professor])) 
as pvt

这是我使用上述查询的输出:

doctor      actor   singer  professor
Samantha    Maria   Priya   Ketty

我可以使用pivot关系运算符来解决这个问题吗?我可以做些什么改变?

2 个答案:

答案 0 :(得分:1)

这个SQL

with data as (
    select * from (values
         ('Samantha', 'Doctor')
        ,('Julia',    'Actor')
        ,('Maria',    'Actor')
        ,('Meera',    'Singer')
        ,('Ashely',   'Professor')
        ,('Ketty',    'Professor')
        ,('Christeen','Professor')
        ,('Jane',     'Actor')
        ,('Jenny',    'Doctor')
        ,('Priya',    'Singer')
    )t(Name,Occupation)
),
groups as (
    select
        Name,Occupation,
        RowNo = row_number() over (partition by Occupation order by Name)
    from data
)
select
    Doctor,Professor,Singer,Actor
from groups
pivot (max(Name) for occupation in (Doctor,Professor, Singer,Actor) ) as pvt
;

的产率:

Doctor    Professor Singer    Actor
--------- --------- --------- ---------
Jenny     Ashely    Meera     Jane
Samantha  Christeen Priya     Julia
NULL      Ketty     NULL      Maria

答案 1 :(得分:1)

我倾向于使用条件聚合来解决这些问题:

select max(case when occupation = 'Doctor' then Name end) as doctor,
       max(case when occupation = 'Actor' then Name end) as actor,
       max(case when occupation = 'Singer' then Name end) as singer,
       max(case when occupation = 'Professor' then Name end) as professor     
from (select t.*,
             row_number() over (partition by occupation order by name) as seqnum
      from thistable t
     ) t
group by seqnum
order by seqnum;