如何在多列上进行透视

时间:2014-06-17 09:56:50

标签: sql-server

这是我的样本表结构

create table ##table1 (user_id int,plan_id int)
insert into ##table1 values(1,1)
insert into ##table1 values(2,1)
insert into ##table1 values(3,2)
insert into ##table1 values(4,2)
insert into ##table1 values(5,1)

select *From ##table1

create table ##payment (user_id int,dueno int,amount float)
insert into ##payment values(1,1,1000)
insert into ##payment values(2,1,1000)
insert into ##payment values(3,1,500)
insert into ##payment values(3,2,500)
insert into ##payment values(4,3,1500)
insert into ##payment values(5,2,100)
insert into ##payment values(5,1,100)

select *from ##payment

这是我到目前为止所做的:

with help as
(
    select a.user_id,a.plan_id,b.amount,b.dueno 
    from ##table1 as a 
         inner join ##payment as b on a.user_id=b.user_id
)
select *from  help pivot (sum(amount) for plan_id in ([1],[2],[3]))as pvt;

这就是我被困的地方。

预期结果:

user_id  plan1(1to12) plan1(12to24) plan2(1to12) plan2(12to24) plan3(1to12) plan4(12to24)
1         1000         null         null           null         null         null
2         1000         null         null           null         null         null 
3         null         null         1000           null         null         null
4         null         null         1500           null         null         null
5         200          200          null           null         null         null

2 个答案:

答案 0 :(得分:0)

使用SUM + CASE代替枢轴

...
SELECT user_id
      ,SUM(CASE WHEN plan_id = 1 AND dueno BETWEEN 1 AND 12 THEN amount ELSE NULL END) AS [plan1(1to12)]
      ,SUM(CASE WHEN plan_id = 1 AND dueno BETWEEN 12 AND 24 THEN amount ELSE NULL END) AS [plan1(12to24)]
      ,SUM(CASE WHEN plan_id = 2 AND dueno BETWEEN 1 AND 12 THEN amount ELSE NULL END) AS [plan2(1to12)]
      ,SUM(CASE WHEN plan_id = 2 AND dueno BETWEEN 12 AND 24 THEN amount ELSE NULL END) AS [plan2(12to24)]
      ,SUM(CASE WHEN plan_id = 3 AND dueno BETWEEN 1 AND 12 THEN amount ELSE NULL END) AS [plan3(1to12)]
      ,SUM(CASE WHEN plan_id = 4 AND dueno BETWEEN 12 AND 24 THEN amount ELSE NULL END) AS [plan4(12to24)]
FROM help

(你没有说明dueno范围是否具有包容性。你需要相应地调整范围。plan4(12to24)似乎是一个错字)

答案 1 :(得分:0)

可能你可以试试这个。

with help as
(
    select a.user_id,'plan' + CAST(a.plan_id as nvarchar) + '(1 to 12)' as planName , a.plan_id,b.amount,b.dueno 
    from (select distinct plan_id from ##table1) as ids
    left join ##table1 as a on ids.plan_id = a.plan_id
         inner join ##payment as b on a.user_id=b.user_id and b.dueno >= 1 and b.dueno <=12     
    union

    select a.user_id,'plan' + CAST(a.plan_id as nvarchar) + '(13 to 24)' as planName,a.plan_id,b.amount,b.dueno 
    from (select distinct plan_id from ##table1) as ids
    left join ##table1 as a on ids.plan_id = a.plan_id
         left join ##payment as b on a.user_id=b.user_id and b.dueno >= 13 and b.dueno <=24

)
select user_id
,sum([plan1(1 to 12)]) AS [plan1(1 to 12)] 
,sum([plan1(13 to 24)]) AS [plan1(13 to 24)] 
,sum([plan2(1 to 12)]) AS [plan2(13 to 24)] 
,sum([plan3(1 to 12)]) AS [plan3(1 to 12)] 
,sum([plan3(13 to 24)]) AS [plan3(13 to 24)] 
from  help pivot (sum(amount) for planName 
in ([plan1(1 to 12)],[plan1(13 to 24)]
    ,[plan2(1 to 12)],[plan2(13 to 24)]
    ,[plan3(1 to 12)],[plan3(13 to 24)]
    ))as pvt
    group by user_id;