将这些行转换为列

时间:2019-04-17 13:57:23

标签: sql sql-server tsql

我有一个相当复杂的查询,我想知道如何将它们从行转换为列,以便它们以以下格式显示。平均值是应使用的列,总计仅用于提供信息,而无需汇总。

enter image description here

摘录一些当前结果:

enter image description here

SELECT dayofweek                    AS Day, 
       Format(onhour, '00') + ':00' AS Hour, 
       Sum(totals)                  AS Total, 
       Avg(totals)                  AS Average 
FROM   (SELECT Datename(weekday, D.fordate) AS DayOfWeek, 
               H.onhour, 
               Isnull(T.totals, 0)          AS Totals 
        FROM   (SELECT DISTINCT T.fordate 
                FROM   #visit AS T) AS D 
               CROSS apply (VALUES(0), 
                                  (1), 
                                  (2), 
                                  (3), 
                                  (4), 
                                  (5), 
                                  (6), 
                                  (7), 
                                  (8), 
                                  (9), 
                                  (10), 
                                  (11), 
                                  (12), 
                                  (13), 
                                  (14), 
                                  (15), 
                                  (16), 
                                  (17), 
                                  (18), 
                                  (19), 
                                  (20), 
                                  (21), 
                                  (22), 
                                  (23)) AS H(onhour) 
               LEFT OUTER JOIN #visit AS T 
                            ON H.onhour = T.onhour 
                               AND D.fordate = T.fordate) a 
WHERE  onhour NOT IN ( 0, 1, 2, 3, 
                       4, 5, 6, 7, 
                       20, 21, 22, 23 ) 
GROUP  BY dayofweek, 
          onhour 
ORDER  BY CASE 
            WHEN dayofweek = 'Monday' THEN 1 
            WHEN dayofweek = 'Tuesday' THEN 2 
            WHEN dayofweek = 'Wednesday' THEN 3 
            WHEN dayofweek = 'Thursday' THEN 4 
            WHEN dayofweek = 'Friday' THEN 5 
            WHEN dayofweek = 'Saturday' THEN 6 
            WHEN dayofweek = 'Sunday' THEN 7 
          END ASC, 
          onhour 

1 个答案:

答案 0 :(得分:2)

您可以使用交叉表查询来获取结果。

SELECT CONVERT(varchar(8), DATEADD(hh, onhour, 0), 108) + ' - ' 
       + CONVERT(varchar(8), DATEADD(hh, onhour+1, 0), 108) AS Hour, 
       Sum(totals)                  AS Total, 
       Avg(CASE WHEN DayOfWeek = 'Monday'    THEN totals END) AS Monday  , 
       Avg(CASE WHEN dayofweek = 'Tuesday'   THEN totals END) AS Tuesday , 
       Avg(CASE WHEN dayofweek = 'Wednesday' THEN totals END) AS Wednesday, 
       Avg(CASE WHEN dayofweek = 'Thursday'  THEN totals END) AS Thursday, 
       Avg(CASE WHEN dayofweek = 'Friday'    THEN totals END) AS Friday  , 
       Avg(CASE WHEN dayofweek = 'Saturday'  THEN totals END) AS Saturday, 
       Avg(CASE WHEN dayofweek = 'Sunday'    THEN totals END) AS Sunday
FROM   (SELECT Datename(weekday, D.fordate) AS DayOfWeek, 
               H.onhour, 
               Isnull(T.totals, 0)          AS Totals 
        FROM   (SELECT DISTINCT T.fordate 
                FROM   #visit AS T) AS D 
               CROSS apply (VALUES(0), 
                                  (1), 
                                  (2), 
                                  (3), 
                                  (4), 
                                  (5), 
                                  (6), 
                                  (7), 
                                  (8), 
                                  (9), 
                                  (10), 
                                  (11), 
                                  (12), 
                                  (13), 
                                  (14), 
                                  (15), 
                                  (16), 
                                  (17), 
                                  (18), 
                                  (19), 
                                  (20), 
                                  (21), 
                                  (22), 
                                  (23)) AS H(onhour) 
               LEFT OUTER JOIN #visit AS T 
                            ON H.onhour = T.onhour 
                               AND D.fordate = T.fordate) a 
WHERE  onhour NOT IN ( 0, 1, 2, 3, 
                       4, 5, 6, 7, 
                       20, 21, 22, 23 ) 
GROUP  BY onhour 
ORDER  BY onhour;