转置列sql server

时间:2018-06-04 08:36:22

标签: sql-server transpose

我在下面有一个稍微复杂的查询:

with t as (


select a.ID, a.Date_Reported AS [Date Sent],  b.Date_Received AS [Date Returned], 

(datediff(dd, a.date_reported, b.date_received) 
      + CASE WHEN Datepart(dw, b.date_received) = 7 THEN 1 ELSE 0 END 
       - (Datediff(wk, a.date_reported, b.date_received) * 2 ) 
       - CASE WHEN Datepart(dw, b.date_received) = 1 THEN 1 ELSE 0 END + 
       - CASE WHEN Datepart(dw, b.date_received) = 1 THEN 1 ELSE 0 
       END) AS [Time_Spent]

from TX_ext a 
join TX b on b.id on a.id
)

select 
       sum(case when Time_Spent between 0 and 3 then 1 else 0 end) as _0_3_days,
       sum(case when Time_Spent = 4 then 1 else 0 end) as _4_days,
       sum(case when Time_Spent = 5 then 1 else 0 end) as _5_days,
       sum(case when Time_Spent between 6 and 8 then 1 else 0 end) as _6_8_days,
       sum(case when Time_Spent >= 9 then 1 else 0 end) as more_than_9_days,

       avg(case when Time_Spent between 0 and 3 then 100.0 else 0 end) as _0_3_percent,
       avg(case when Time_Spent = 4 then 100.0 else 0 end) as _4_percent,
       avg(case when Time_Spent = 5 then 100.0 else 0 end) as _5_percent,
       avg(case when Time_Spent between 6 and 8 then 100.0 else 0 end) as _6_8_percent,
       avg(case when Time_Spent >= 9 then 100.0 else 0 end) as more_than_9_day_percent
from t

上面的查询给出了下表:

0-3 | 4 | 5 | 6-8 | 9+ | 0-3% | 4% | 5% | 6-8% | 9+%
2   | 3 | 1 | 3   | 1  |  20  | 30 | 10 | 30   | 10

然而,我理想的是这个(%数字转换为一行)以及标题为FIRST专栏:

Time Taken (days) | 0-3 | 4 | 5 | 6-8 | 9+ 
Count             |  2  | 3 | 1 | 3   | 1  
%                 | 20  | 30| 10| 30  | 10 

有什么想法吗?提前致谢

2 个答案:

答案 0 :(得分:1)

您可以使用CROSS APPLY执行此操作,如下面的查询 See live demo

      ; with t as 
   (
        select 
        a.ID, 
        a.Date_Reported AS [Date Sent],  
        b.Date_Received AS [Date Returned], 
        (datediff(dd, a.date_reported, b.date_received) 
          + CASE WHEN Datepart(dw, b.date_received) = 7 THEN 1 ELSE 0 END 
           - (Datediff(wk, a.date_reported, b.date_received) * 2 ) 
           - CASE WHEN Datepart(dw, b.date_received) = 1 THEN 1 ELSE 0 END + 
           - CASE WHEN Datepart(dw, b.date_received) = 1 THEN 1 ELSE 0 
           END) AS [Time_Spent]
        from TX_ext a 
            join TX b on b.id on a.id
    )


    select V.* 
    from 
    (
        select 
           sum(case when Time_Spent between 0 and 3 then 1 else 0 end) as _0_3_days,
           sum(case when Time_Spent = 4 then 1 else 0 end) as _4_days,
           sum(case when Time_Spent = 5 then 1 else 0 end) as _5_days,
           sum(case when Time_Spent between 6 and 8 then 1 else 0 end) as _6_8_days,
           sum(case when Time_Spent >= 9 then 1 else 0 end) as more_than_9_days,

           avg(case when Time_Spent between 0 and 3 then 100.0 else 0 end) as _0_3_percent,
           avg(case when Time_Spent = 4 then 100.0 else 0 end) as _4_percent,
           avg(case when Time_Spent = 5 then 100.0 else 0 end) as _5_percent,
           avg(case when Time_Spent between 6 and 8 then 100.0 else 0 end) as _6_8_percent,
           avg(case when Time_Spent >= 9 then 100.0 else 0 end) as more_than_9_day_percent
    from t
    ) T1
    cross apply 
    ( values 
      ('Count',[_0_3_days] , [_4_days] , [_5_days] , [_6_8_days] ,  [more_than_9_days]),
    ('%',[_0_3_percent] , [_4_percent] , [_5_percent] ,  [_6_8_percent] , [more_than_9_day_percent] )
    )
    v([Time Taken (days)],[0-3],[4],[5],[6-8],[9+])

答案 1 :(得分:0)

select 
   sum(case when Time_Spent between 0 and 3 then 1 else 0 end) as _0_3,
   sum(case when Time_Spent = 4 then 1 else 0 end) as _4,
   sum(case when Time_Spent = 5 then 1 else 0 end) as _5,
   sum(case when Time_Spent between 6 and 8 then 1 else 0 end) as _6_8,
   sum(case when Time_Spent >= 9 then 1 else 0 end) as more_than_9
from t
union
select
   avg(case when Time_Spent between 0 and 3 then 100.0 else 0 end) as _0_3,
   avg(case when Time_Spent = 4 then 100.0 else 0 end) as _4,
   avg(case when Time_Spent = 5 then 100.0 else 0 end) as _5,
   avg(case when Time_Spent between 6 and 8 then 100.0 else 0 end) as _6_8,
   avg(case when Time_Spent >= 9 then 100.0 else 0 end) as more_than_9
from t