PIVOT数据是分开的

时间:2013-12-04 10:22:06

标签: sql sql-server pivot

以下是重现问题的查询:

declare @tbl1  table (
    name varchar(50),
    cnttype     varchar(50),
    avgcnt int,
    totaltype   varchar(50),
    avgtotal int
)

insert into @tbl1 values('test','2c',2,'2t',483162)
insert into @tbl1 values('test','3c',1,'3t',6395915)
insert into @tbl1 values('test','1c',6,'1t',0)

select name, [1c] as [balance count], [1t] as [balance avg] 
, [2c] as [bill count], [2t] as [bill avg]
, [3c] as [cash count], [3t] as [cash avg]
 from
 (select * from @tbl1) raw1
pivot( sum(avgcnt) for cnttype in ([1c], [2c], [3c]) ) pvt
pivot( sum(avgtotal) for totaltype in ([1t], [2t], [3t]) ) pvt2

如您所见,输出为:

name    balance count   balance avg bill count  bill avg    cash count  cash avg
test    NULL    NULL    NULL    NULL    1   6395915
test    NULL    NULL    2   483162  NULL    NULL
test    6   0   NULL    NULL    NULL    NULL

但我希望只看到一行:

name    balance count   balance avg bill count  bill avg    cash count  cash avg
test    6   0   2   483162  1   6395915

你能告诉我我的错误是什么吗?

2 个答案:

答案 0 :(得分:1)

我认为使用带有CASE表达式的聚合函数来获得这个结果要容易得多:

select name,
  sum(case when cnttype = '1c' then avgcnt end) balanceCount,
  sum(case when totaltype = '1t' then avgtotal end) balanceAvg,
  sum(case when cnttype = '2c' then avgcnt end) billCount,
  sum(case when totaltype = '2t' then avgtotal end) billAvg,
  sum(case when cnttype = '3c' then avgcnt end) cashCount,
  sum(case when totaltype = '3t' then avgtotal end) cashAvg
from @tbl1
group by name;

请参阅SQL Fiddle with Demo

这也可以通过首先取消cnttypetotaltype列,然后应用枢轴函数来完成。

;with cte as
(
  select name, col = 
    case left(col, 1)
      when 1 then 'balance'
      when 2 then 'bill'
      when 3 then 'cash'
    end + txt, value
  from @tbl1
  cross apply
  (
    select 'Count', cnttype, avgcnt union all
    select 'Avg', totaltype, avgtotal
  ) c (txt, col, value)
)
select name, 
  balanceCount, balanceAvg, 
  billCount, billAvg,
  cashCount, cashAvg
from cte
pivot
(
    sum(value)
    for col in (balanceCount, balanceAvg, 
                billCount, billAvg,
                cashCount, cashAvg)
) piv;

SQL Fiddle with Demo。这些都会产生结果:

| NAME | BALANCECOUNT | BALANCEAVG | BILLCOUNT | BILLAVG | CASHCOUNT | CASHAVG |
|------|--------------|------------|-----------|---------|-----------|---------|
| test |            6 |          0 |         2 |  483162 |         1 | 6395915 |

答案 1 :(得分:0)

请尝试:

select 
    name, 
    max([1c]) as [balance count], 
    max([1t]) as [balance avg], 
    max([2c]) as [bill count], 
    max([2t]) as [bill avg], 
    max([3c]) as [cash count], 
    max([3t]) as [cash avg]
 from
 (select * from @tbl1) raw1
  pivot( sum(avgcnt) for cnttype in ([1c], [2c], [3c]) ) pvt
  pivot( sum(avgtotal) for totaltype in ([1t], [2t], [3t]) 
) pvt2
group by name