SQL 转置全表

问题描述 投票:0回答:2

我需要在 MS SQL 中进行以下转置

来自:

Day  A  B 
---------
Mon  1  2
Tue  3  4
Wed  5  6
Thu  7  8
Fri  9  0

致以下人士:

Value Mon Tue Wed Thu Fri 
--------------------------
A      1   3   5   7   9
B      2   4   6   8   0

我明白当只有一列(A)时如何使用

PIVOT
,但我不知道当有多列需要转置(A,B,...)时如何做到这一点

要转置的示例代码:

select LEFT(datename(dw,datetime),3) as DateWeek, 
  sum(ACalls) as A, 
  Sum(BCalls) as B 
from DataTable
group by LEFT(datename(dw,datetime),3)

表结构:

Column DataType
DateTime Datetime
ACalls int
BCalls int

任何帮助将不胜感激。

sql sql-server pivot unpivot
2个回答
30
投票

为了将数据转置为您想要的结果,您需要使用

UNPIVOT
PIVOT
函数。

UNPIVOT
函数采用
A
B
列并将结果转换为行。然后,您将使用
PIVOT
函数将
day
值转换为列:

select *
from
(
  select day, col, value
  from yourtable
  unpivot
  (
    value
    for col in (A, B)
  ) unpiv
) src
pivot
(
  max(value)
  for day in (Mon, Tue, Wed, Thu, Fri)
) piv

请参阅 SQL Fiddle 演示

如果您使用的是 SQL Server 2008+,则可以使用

CROSS APPLY
VALUES
来逆透视数据。您的代码将更改为以下内容:

select *
from
(
  select day, col, value
  from yourtable
  cross apply
  (
    values ('A', A),('B', B)
  ) c (col, value)
) src
pivot
(
  max(value)
  for day in (Mon, Tue, Wed, Thu, Fri)
) piv

请参阅 SQL Fiddle 演示

编辑 #1,将当前查询应用到上述解决方案中,您将使用与此类似的内容:

select *
from
(
  select LEFT(datename(dw,datetime),3) as DateWeek,
    col, 
    value
  from DataTable 
  cross apply 
  (
    values ('A', ACalls), ('B', BCalls)
  ) c (col, value)
) src
pivot
(
  sum(value)
  for dateweek in (Mon, Tue, Wed, Thu, Fri)
) piv

0
投票
with orig as
(
select 'Mon' as day_,   1 as A,  2 as B from dual union all 
select 'Tue',  3,  4 from dual union all 
select 'Wed',  5,  6 from dual union all 
select 'Thu',  7,  8 from dual union all 
select 'Fri',  9,  0 from dual union all 
select 'Sat',  10,  1 from dual union all 
select 'Sun',  11,  5 from dual 
)
, chg1 as
(
select col_, day_, case when col_='A' then A else B end  AorB
from orig cross join (select 'A' col_ from dual union all select 'B' col_ from dual)
)
  
select 
   col_
 , max(case when day_='Mon' then AorB else null end) Mon
 , max(case when day_='Tue' then AorB else null end) Tue
 , max(case when day_='Wed' then AorB else null end) Wed
 , max(case when day_='Thu' then AorB else null end) Thu
 , max(case when day_='Fri' then AorB else null end) Fri
 , max(case when day_='Sat' then AorB else null end) Sat
 , max(case when day_='Sun' then AorB else null end) Sun
from chg1
group by col_
© www.soinside.com 2019 - 2024. All rights reserved.