Oracle 行转列 pivot函数基本用法

一、运行环境

  • 目前该语法使用Oracle11g+版本,首先请核实你的数据库版本是否支持该语法;
select * from v$version;

二、看下结果

Oracle 行转列 pivot函数基本用法_第1张图片Oracle 行转列 pivot函数基本用法_第2张图片
三、测试数据准备

--建表
--drop table SalesList;
create table SalesList(
    keHu                varchar2(20),   --客户
    shangPin            varchar2(20),   --商品名称
    salesNum            number(8)       --销售数量
);
 
--插入数据
declare
  --谈几个客户
  cursor lr_kh is 
  select regexp_substr('张三、李四、王五、赵六','[^、]+',1, level) keHu from dual
   connect by level <= 4;
  --进点货
  cursor lr_sp is 
  select regexp_substr('上衣、裤子、袜子、帽子','[^、]+',1, level) shangPin from dual
   connect by level <= 4;
begin
  --循环插入
  for v_kh in lr_kh loop
     for v_sp in lr_sp loop
        insert into SalesList
        select v_kh.keHu, v_sp.shangPin, floor(dbms_random.value(10,50)) from dual;
     end loop;
  end loop;
  commit;
end;
/


四、pivot进行转换的SQL(查询结果就是上面的结果图)

--行转列
select *
  from SalesList pivot(
    max(salesNum) for shangPin in (    --shangPin 即要转成列的字段
        '上衣' as 上衣,                 --max(salesNum) 此处必须为聚合函数,
        '裤子' as 裤子,                 --in () 对要转成列的每一个值指定一个列名
        '袜子' as 袜子,
        '帽子' as 帽子
    )
  )
 where 1 = 1;                          --这里可以写查询条件,没有可以直接不要where

扩展:

4.1 单例透视


现在,我们要查询某个产品在某个渠道销售金额总和情况;

SELECT *
  FROM (SELECT product, channel, amount_sold FROM sales) S
PIVOT(SUM(amount_sold)
   FOR CHANNEL IN(3 AS 直营店,
                  4 AS 电商,
                  5 AS 自媒体,
                  9 AS 加盟店))
 ORDER BY product;

Oracle 行转列 pivot函数基本用法_第3张图片

4.2 多列透视


现在,我们要查询某个产品在某个渠道和某个季度,销售数量的总和;

 SELECT *
   FROM (SELECT product, channel, quarter, quantity_sold FROM sales)
 PIVOT(SUM(quantity_sold)
    FOR(channel, quarter) IN((5, '03') AS 自媒体三季度销售量,
                             (4, '02') AS 电商二季度销售量,
                             (3, '01') AS 直营店一季度销售量,
                             (3, '02') AS 直营店二季度销售量,
                             (9, '04') AS 加盟店四季度销售量));

Oracle 行转列 pivot函数基本用法_第4张图片

4.3 多个聚合


现在我们要查询某个产品在某个渠道的销售金额总和以及销售数量总和;

SELECT *
  FROM (SELECT product, channel, amount_sold, quantity_sold FROM sales)
PIVOT(SUM(amount_sold) AS sums, SUM(quantity_sold) AS sumq
   FOR channel IN(5, 4, 3, 9))
 ORDER BY product;

Oracle 行转列 pivot函数基本用法_第5张图片
 

 

 


五、转动态列


有时候可能需要行转列的值,即shangPin字段的值的个数很多,或者是不确定个数,那 in () 里面的部分就不好去写死,然后,Oracle的pivot其实也是提供了一个转出动态列的功能,不过转出来的是xml格式的数据。。。这也是为啥我说要自己写一个处理的方法的原因了、、、不过具体做法下次再说,现在先看下原汁原味的转xml的做法,sql如下:
还是有点感人的。不过这样的结果,实在是,,用途不大。

--动态出列(xml的形式)
select *
  from SalesList pivot xml(                        --pivot xml 以xml的形式输出
    max(salesNum) for shangPin in (
       select distinct shangPin from SalesList     --通过查询查出所有需要转列的值,即所有列名
    )
  );

 

所以呢,要么,咱们把这个xml的结果,转换成你要的结果,又要么呢,咱们写个存储过程什么的,通过一些参数,配置,把数据处理成咱们需要的效果。

我个人是比较倾向与存储过程处理,可以通过动态sql拼接,或者是循环的方式处理,具体实现,下期再聊。
 

 

你可能感兴趣的:(数据库)