SQL : 查询数据的pivot方式

SQL : Pivot way to query data

我有一个 table,如下所示。我想查询行数据并将其显示为列

Customer  MetricName MetricValue    Date
 A          Upload    2          10-AUG-2007
 A          Download  2          10-AUG-2007
 A          Storage   100        10-AUG-2007
 A          Storage   110        11-AUG-2007
 B          Storage   200        11-AUG-2007
 A          Upload    2          12-AUG-2007
 A          Download  2          12-AUG-2007
 B          Upload    2          10-AUG-2007
 B          Download  2          10-AUG-2007

上周使​​用情况

下载 - 一周内所有下载的总和 存储 - 本周最高值

 Customer  Download  Upload   Storage
   A          4        4        110
   B          2        2        200

如何使用 Pivot 或其他方法实现此目的

类似这样...PIVOT 需要将相同的聚合函数应用于所有列;使用 case 表达式的旧 "manual" 旋转方式更加灵活(如下所示)。我不确定 "week" 是什么意思 - 我只是把它放在 WHERE 子句中。另外,不要对列(或 table)名称使用像 DATE 这样的保留字,你不能直接这样做,也不应该用唯一可能的方式(使用双引号)——这是一个非常糟糕的方法实践。我将列名称 Date 更改为 dt

with 
     input_data ( customer, metricname, metricvalue, dt ) AS (
       select 'A', 'Upload'  ,  2   , to_date('10-AUG-2007', 'dd-MON-yyyy') from dual union all
       select 'A', 'Download',  2   , to_date('10-AUG-2007', 'dd-MON-yyyy') from dual union all
       select 'A', 'Storage' ,  100 , to_date('10-AUG-2007', 'dd-MON-yyyy') from dual union all
       select 'A', 'Storage' ,  110 , to_date('11-AUG-2007', 'dd-MON-yyyy') from dual union all
       select 'B', 'Storage' ,  200 , to_date('11-AUG-2007', 'dd-MON-yyyy') from dual union all
       select 'A', 'Upload'  ,  2   , to_date('12-AUG-2007', 'dd-MON-yyyy') from dual union all
       select 'A', 'Download',  2   , to_date('12-AUG-2007', 'dd-MON-yyyy') from dual union all
       select 'B', 'Upload'  ,  2   , to_date('10-AUG-2007', 'dd-MON-yyyy') from dual union all
       select 'B', 'Download',  2   , to_date('10-AUG-2007', 'dd-MON-yyyy') from dual
     )
select   customer,
         sum( case when metricname = 'Upload'   then metricvalue end) as upload,
         sum( case when metricname = 'Download' then metricvalue end) as download,
         max( case when metricname = 'Storage'  then metricvalue end) as storage
from     input_data
where    dt between to_date('09-AUG-2007', 'dd-MON-yyyy') and 
                                               to_date('15-AUG-2007', 'dd-MON-yyyy')
group by customer
order by customer
;

CUSTOMER     UPLOAD   DOWNLOAD    STORAGE
-------- ---------- ---------- ----------
A                 4          4        110
B                 2          2        200