https://www.cnblogs.com/mellowsmile/p/4642306.html
HH
终风且暴,顾我则笑,谑浪笑敖,中心是悼。 终风且霾,惠然肯来,莫往莫来,悠悠我思。
Oracle行转列、列转行的Sql语句总结 多行转字符串 这个比较简单,用||或concat函数可以实现
SQL Code
1 2 |
|
select concat(id,username) str from app_user select id||username str from app_user |
字符串转多行 使用union all函数等方式
wm_concat函数 首先让我们来看看这个神奇的函数wm_concat(列名),该函数可以把列值以","号分隔起来,并显示成一行,接下来上例子,看看这个神奇的函数如何应用准备测试数据
SQL Code
1 2 3 4 5 6 |
|
create table test(id number,name varchar2(20));
insert into test values(1,'a'); insert into test values(1,'b'); insert into test values(1,'c'); insert into test values(2,'d'); insert into test values(2,'e'); |
SQL Code
1 |
|
select wm_concat(name) name from test;
|
文章图片
效果2: 把结果里的逗号替换成"|"
SQL Code
1 |
|
select replace(wm_concat(name),',','|') from test;
|
文章图片
效果3: 按ID分组合并name
SQL Code
1 |
|
select id,wm_concat(name) name from test group by id;
|
文章图片
sql语句等同于下面的sql语句:
SQL Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
|
-------- 适用范围:8i,9i,10g及以后版本( MAX + DECODE ) select id, max(decode(rn, 1, name, null)) || max(decode(rn, 2, ',' || name, null)) || max(decode(rn, 3, ',' || name, null)) str from (select id, name, row_number() over(partition by id order by name) as rn from test) t group by id order by 1; -------- 适用范围:8i,9i,10g及以后版本 ( ROW_NUMBER + LEAD ) select id, str from (select id, row_number() over(partition by id order by name) as rn, name || lead(',' || name, 1) over(partition by id order by name) || lead(',' || name, 2) over(partition by id order by name) || lead(',' || name, 3) over(partition by id order by name) as str from test) where rn = 1 order by 1; -------- 适用范围:10g及以后版本 ( MODEL ) select id, substr(str, 2) str from test model return updated rows partition by(id) dimension by(row_number() over(partition by id order by name) as rn) measures(cast(name as varchar2(20)) as str) rules upsert iterate(3) until(presentv(str [ iteration_number + 2 ], 1, 0) = 0) (str [ 0 ] = str [ 0 ] || ',' || str [ iteration_number + 1 ]) order by 1; -------- 适用范围:8i,9i,10g及以后版本 ( MAX + DECODE ) select t.id id, max(substr(sys_connect_by_path(t.name, ','), 2)) str from (select id, name, row_number() over(partition by id order by name) rn from test) t start with rn = 1 connect by rn = prior rn + 1 and id = prior id group by t.id; |
懒人扩展用法:
案例: 我要写一个视图,类似"create or replace view as select 字段1,...字段50 from tablename" ,基表有50多个字段,要是靠手工写太麻烦了,有没有什么简便的方法? 当然有了,看我如果应用wm_concat来让这个需求变简单,假设我的APP_USER表中有(id,username,password,age)4个字段。查询结果如下
SQL Code
1 2 3 4 5 |
|
/** 这里的表名默认区分大小写 */ select 'create or replace view as select ' || wm_concat(column_name) || ' from APP_USER' sqlStr from user_tab_columns where table_name = 'APP_USER'; |
文章图片
利用系统表方式查询
SQL Code
1 |
|
select * from user_tab_columns |
参考:http://blog.csdn.net/tianlesoftware/article/details/7060306、http://www.oracle.com/technetwork/cn/articles/11g-pivot-101924-zhs.html
google 一下,网上有一篇比较详细的文档:http://www.oracle-developer.net/display.php?id=506
pivot 列转行
测试数据 (id,类型名称,销售数量),案例:根据水果的类型查询出一条数据显示出每种类型的销售数量。
SQL Code
1 2 3 4 5 6 7 8 9 |
|
create table demo(id int,name varchar(20),nums int);
---- 创建表 insert into demo values(1, '苹果', 1000); insert into demo values(2, '苹果', 2000); insert into demo values(3, '苹果', 4000); insert into demo values(4, '橘子', 5000); insert into demo values(5, '橘子', 3000); insert into demo values(6, '葡萄', 3500); insert into demo values(7, '芒果', 4200); insert into demo values(8, '芒果', 5500); |
文章图片
分组查询 (当然这是不符合查询一条数据的要求的)
SQL Code
1 |
|
select name, sum(nums) nums from demo group by name |
文章图片
行转列查询
SQL Code
1 |
|
select * from (select name, nums from demo) pivot (sum(nums) for name in ('苹果' 苹果, '橘子', '葡萄', '芒果'));
|
文章图片
注意: pivot(聚合函数 for 列名 in(类型)) ,其中 in('') 中可以指定别名,in中还可以指定子查询,比如 select distinct code from customers
当然也可以不使用pivot函数,等同于下列语句,只是代码比较长,容易理解
SQL Code
1 2 3 4 5 |
|
select * from (select sum(nums) 苹果 from demo where name = '苹果'), (select sum(nums) 橘子 from demo where name = '橘子'), (select sum(nums) 葡萄 from demo where name = '葡萄'), (select sum(nums) 芒果 from demo where name = '芒果'); |
顾名思义就是将多列转换成1列中去
案例:现在有一个水果表,记录了4个季度的销售数量,现在要将每种水果的每个季度的销售情况用多行数据展示。
创建表和数据
SQL Code
1 2 3 4 5 6 |
|
create table Fruit(id int,name varchar(20), Q1 int, Q2 int, Q3 int, Q4 int);
insert into Fruit values(1,'苹果',1000,2000,3300,5000); insert into Fruit values(2,'橘子',3000,3000,3200,1500); insert into Fruit values(3,'香蕉',2500,3500,2200,2500); insert into Fruit values(4,'葡萄',1500,2500,1200,3500); select * from Fruit |
文章图片
列转行查询
SQL Code
1 |
|
select id , name, jidu, xiaoshou from Fruit unpivot (xiaoshou for jidu in (q1, q2, q3, q4) ) |
文章图片
同样不使用unpivot也可以实现同样的效果,只是sql语句会很长,而且执行速度效率也没有前者高
SQL Code
1 2 3 4 5 6 7 |
|
select id, name ,'Q1' jidu, (select q1 from fruit where id=f.id) xiaoshou from Fruit f union select id, name ,'Q2' jidu, (select q2 from fruit where id=f.id) xiaoshou from Fruit f union select id, name ,'Q3' jidu, (select q3 from fruit where id=f.id) xiaoshou from Fruit f union select id, name ,'Q4' jidu, (select q4 from fruit where id=f.id) xiaoshou from Fruit f |
上述pivot列转行示例中,你已经知道了需要查询的类型有哪些,用in()的方式包含,假设如果您不知道都有哪些值,您怎么构建查询呢?
pivot 操作中的另一个子句 XML 可用于解决此问题。该子句允许您以 XML 格式创建执行了 pivot 操作的输出,在此输出中,您可以指定一个特殊的子句 ANY 而非文字值
示例如下:
SQL Code
1 2 3 4 5 6 7 |
|
select * from ( select name, nums as "Purchase Frequency" from demo t ) pivot xml ( sum(nums) for name in (any) ) |
文章图片
如您所见,列 NAME_XML 是 XMLTYPE,其中根元素是 。每个值以名称-值元素对的形式表示。您可以使用任何 XML 分析器中的输出生成更有用的输出。
文章图片
对于该xml文件的解析,贴代码如下:
SQL Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
create or replace procedure ljz_pivot_xml_sp(pi_table_namevarchar2, pi_column_namevarchar2, pi_create_table varchar2) as v_columnnvarchar2(50); v_countnumber := 0; v_inumber; v_parent_node nvarchar2(4000); v_child_nodenvarchar2(4000); v_overboolean := false; v_tmpnvarchar2(50); v_existsnodenumber; v_sqlclob; v_namevarchar2(30); v_name_xmlxmltype; begin v_sql:= 'select x.* from ' || pi_table_name || ' a, xmltable(''/PivotSet'' passing a.' || pi_column_name || ' columns '; v_parent_node := '/PivotSet'; v_child_node:= 'item[1]/column[2]'; v_i:= 1; execute immediate 'select ' || pi_column_name || ' from ' || pi_table_name || ' where rownum=1' into v_name_xml; select existsnode(v_name_xml, '/PivotSet/item[' || to_char(v_i) || ']/column[1]') into v_existsnode from dual; while v_existsnode = 1 loop execute immediate 'select substr(extractvalue(' || pi_column_name || ', ''/PivotSet/item[' || to_char(v_i) || ']/column[1]''),1,30) from ' || pi_table_name || ' x' into v_name; v_sql := v_sql || '"' || v_name || '" varchar2(30) path ''item[' || to_char(v_i) || ']/column[2]'','; v_i:= v_i + 1; select existsnode(v_name_xml, '/PivotSet/item[' || to_char(v_i) || ']/column[1]') into v_existsnode from dual; end loop; v_sql := trim(',' from v_sql) || ') x'; commit; select count(1) into v_count from user_tab_columns where table_name = upper(pi_create_table); if v_count = 0 then execute immediate 'create table ' || pi_create_table || ' as ' || v_sql; end if; end; |
第一个参数为要解析xml文件所属数据表,第二个参数为要解析xml所存字段,第三个参数存放解析后的数据集。
测试:
begin
ljz_pivot_xml_sp('(select * from (select deptno,sal from emp) pivot xml(sum(sal) for deptno in(any)))',
'deptno_xml',
'ljz_pivot_tmp');
end;
文章图片
初学oracle xml解析,这种方法较为笨拙,一个一个循环列,原型如下:
select extractvalue(name_xml, '/PivotSet/item[1]/column[1]')
from (select * from (select name,nums from demo) pivot xml(sum(nums) for name in(any))) x
where existsnode(name_xml, '/PivotSet/item[1]/column[1]') = 1;
文章图片
select x.*
from (select *
from (select name, nums from demo)
pivot xml(sum(nums)
for name in(any))) a,
xmltable('/PivotSet' passing a.name_xml columns
芒果 varchar2(30) path 'item[1]/column[2]',
苹果 varchar2(30) path 'item[2]/column[2]') x
文章图片
不知是否存在直接进行解析的方法,这种方法还不如直接行列转变,不通过xml转来转去。
select '''' || listagg(substr(name, 1, 30), q'{','}') within group(order by name) || ''''
from (select distinct name from demo);
文章图片
select *
from (select name, nums from demo)
pivot(sum(nums)
for name in('苹果', '橘子', '葡萄', '芒果'));
文章图片
这样拼接字符串反而更加方便。
结论 Pivot 为 SQL 语言增添了一个非常重要且实用的功能。您可以使用 pivot 函数针对任何关系表创建一个交叉表报表,而不必编写包含大量 decode 函数的令人费解的、不直观的代码。同样,您可以使用 unpivot 操作转换任何交叉表报表,以常规关系表的形式对其进行存储。Pivot 可以生成常规文本或 XML 格式的输出。如果是 XML 格式的输出,您不必指定 pivot 操作需要搜索的值域。
分类: Oracle 相关
好文要顶 关注我 收藏该文
文章图片
文章图片
文章图片
mellowsmile
关注 - 3
粉丝 - 24
+加关注
3
1
? 上一篇:Oracle发送邮件,支持HTML,多收件人,多附件
? 下一篇:Oracle用法、函数备忘记录
posted @ 2015-07-13 10:54 mellowsmile 阅读(134290) 评论(7) 编辑 收藏
https://www.cnblogs.com/mellowsmile/p/4642306.html
https://blog.csdn.net/wyqwilliam/article/details/82559023
原
SQL行转列、列转行 2018年09月09日 15:51:14 道法—自然 阅读数:182
SQL行转列、列转行
这个主题还是比较常见的,行转列主要适用于对数据作聚合统计,如统计某类目的商品在某个时间区间的销售情况。列转行问题同样也很常见。
一、整理测试数据
-
create table wyc_test(
-
id int(32) not null auto_increment,
-
name varchar(80) default null,
-
date date default null,
-
scount int(32),
-
primary key (id)
-
);
-
INSERT INTO `wyc_test` (`id`,`name`,`date`,`scount`) VALUES (1,'小说','2013-09-01',10000);
-
INSERT INTO `wyc_test` (`id`,`name`,`date`,`scount`) VALUES (2,'微信','2013-09-01',20000);
-
INSERT INTO `wyc_test` (`id`,`name`,`date`,`scount`) VALUES (3,'小说','2013-09-02',30000);
-
INSERT INTO `wyc_test` (`id`,`name`,`date`,`scount`) VALUES (4,'微信','2013-09-02',35000);
-
INSERT INTO `wyc_test` (`id`,`name`,`date`,`scount`) VALUES (5,'小说','2013-09-03',31000);
-
INSERT INTO `wyc_test` (`id`,`name`,`date`,`scount`) VALUES (6,'微信','2013-09-03',36000);
-
INSERT INTO `wyc_test` (`id`,`name`,`date`,`scount`) VALUES (7,'小说','2013-09-04',35000);
-
INSERT INTO `wyc_test` (`id`,`name`,`date`,`scount`) VALUES (8,'微信','2013-09-04',38000);
-
INSERT INTO `wyc_test` (`id`,`name`,`date`,`scount`) VALUES (9,'小说','2013-09-01',80000);
-
INSERT INTO `wyc_test` (`id`,`name`,`date`,`scount`) VALUES (10,'微信','2013-09-01',70000);
主要思路是分组后使用case进行条件判断处理
-
#行转列
-
select
-
a.date,
-
sum(case a.name
-
when '小说' then a.scount
-
else 0
-
end) 'sum_小说',
-
max(case a.name
-
when '小说' then a.scount
-
else 0
-
end) 'max_小说',
-
sum(case a.name
-
when '微信' then a.scount
-
else 0
-
end) '微信',
-
max(case a.name
-
when '小说' then a.scount
-
else 0
-
end) 'max_微信'
-
from
-
wyc_test a
-
group by date;
文章图片
三、列转行
主要思路也是分组后使用case
-
#列转行
-
select
-
a.date,
-
concat('小说:',
-
cast(sum(case a.name
-
when '小说' then a.scount
-
else 0
-
end)
-
as char),
-
'微信',
-
cast(sum(case a.name
-
when '微信' then a.scount
-
else 0
-
end)
-
as char)) as 'str'
-
from
-
wyc_test a
-
group by a.date;
-
#列转行
-
#1.使用mysql提供的函数分组
-
select a.date,group_concat(a.name,'总量:', a.scount) from wyc_test a group by a.date,a.name;
-
#2.使用mysql提供的函数分组
-
select a.date,a.name, group_concat(a.name, '总量:', a.scount) from wyc_test a group by a.date,a.name;
-
#3.普通group结合字符串拼接
-
SELECT
-
a.date,
-
concat('小说总量:',
-
cast(sum(case a.name
-
when '小说' then a.scount
-
else 0
-
end)
-
as char)) as '小说',
-
concat('微信总量:',
-
cast(sum(case a.name
-
when '微信' then a.scount
-
else 0
-
end)
-
as char)) as '微信'
-
from
-
wyc_test a
-
group by a.date;
文章图片
四、列转行详解
1.1、初始测试数据
表结构:TEST_TB_GRADE2
Sql代码
create table TEST_TB_GRADE2
(
IDNUMBER(10) not null,
USER_NAMEVARCHAR2(20 CHAR),
CN_SCOREFLOAT,
MATH_SCORE FLOAT,
EN_SCOREFLOAT
)
初始数据如下图:
文章图片
1.2、 如果需要实现如下的查询效果图:
文章图片
这就是最常见的列转行,主要原理是利用SQL里面的union,具体的sql语句如下:
Sql代码
select user_name, '语文' COURSE , CN_SCORE as SCORE from test_tb_grade2
union select user_name, '数学' COURSE, MATH_SCORE as SCORE from test_tb_grade2
union select user_name, '英语' COURSE, EN_SCORE as SCORE from test_tb_grade2
order by user_name,COURSE
也可以利用【 insert all into ... select 】来实现,首先需要先建一个表TEST_TB_GRADE3:
Sql代码
create table TEST_TB_GRADE3
(
USER_NAME VARCHAR2(20 CHAR),
COURSEVARCHAR2(20 CHAR),
SCOREFLOAT
)
再执行下面的sql:
Sql代码
insert all
into test_tb_grade3(USER_NAME,COURSE,SCORE) values(user_name, '语文', CN_SCORE)
into test_tb_grade3(USER_NAME,COURSE,SCORE) values(user_name, '数学', MATH_SCORE)
into test_tb_grade3(USER_NAME,COURSE,SCORE) values(user_name, '英语', EN_SCORE)
select user_name, CN_SCORE, MATH_SCORE, EN_SCORE from test_tb_grade2;
commit;
别忘记commit操作,然后再查询TEST_TB_GRADE3,发现表中的数据就是列转成行了。
收藏
分享
https://blog.csdn.net/wyqwilliam/article/details/82559023
https://www.cnblogs.com/wayne-ivan/p/6416489.html
博客园首页新随笔联系管理订阅
文章图片
wm_concat函数的排序问题 wm_concat在行转列的时候非常有用,但在行转列的过程中的排序问题常常难以控制。
可见下面例子:
准备测试表:
drop table t;
create table t (n number,m number);
insert into t values(1,1);
insert into t values(5,3);
insert into t values(3,3);
insert into t values(6,5);
insert into t values(7,2);
insert into t values(2,2);
insert into t values(0,1);
insert into t values(11,1);
insert into t values(15,3);
insert into t values(13,3);
insert into t values(16,5);
insert into t values(17,2);
insert into t values(12,2);
insert into t values(10,1);
commit;
SQL> select * from t order by 2,1;
N M
———- ———-
0 1
1 1
10 1
11 1
2 2
7 2
12 2
17 2
3 3
5 3
13 3
15 3
6 5
16 5
测试wm_concat后的顺序:
测试1:
SQL> select m,wm_concat(n) from t group by m;
M WM_CONCAT(N)
———- ——————————————————————————–
1 11,0,1,10
2 17,2,7,12
3 15,3,5,13
5 16,6
可见wm_concat后的顺序并没有按大->小,或小->大的顺序。
测试2:
–参考网上一些解决思路
SQL> select m,wm_concat(n)
2 from (select n,m from t order by m,n )
3 group by m;
M WM_CONCAT(N)
———- ——————————————————————————–
1 0,11,10,1
2 2,17,12,7
3 3,15,13,5
5 6,16
可见顺序问题还是没有解决
最终解决思路:
SQL> select m, max(r)
2 from (select m, wm_concat(n) over (partition by m order by n) r from t)
3 group by m ;
M MAX(R)
———- ——————————————————————————–
1 0,1,10,11
2 2,7,12,17
3 3,5,13,15
5 6,16
分类: Oracle
好文要顶 关注我 收藏该文
文章图片
文章图片
文章图片
伊凡
关注 - 0
粉丝 - 86
+加关注
0
0
? 上一篇:Oracle树查询及相关函数
? 下一篇:Oracle系统表整理+常用SQL语句收集
posted @ 2017-02-19 18:23 伊凡 阅读(8665) 评论(0) 编辑 收藏
https://www.cnblogs.com/wayne-ivan/p/6416489.html
https://blog.csdn.net/seandba/article/details/72730657
原
Oracle SQL函数pivot、unpivot转置函数实现行转列、列转行 2017年05月25日 16:18:27 Seandba 阅读数:26664
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Seandba/article/details/72730657
函数PIVOT、UNPIVOT转置函数实现行转列、列转行,效果如下图所示:
1.PIVOT为行转列,从图示的左边到右边
2.UNPIVOT为列转行,从图示的右边到左边
3.左边为纵表,结构简单,易扩展
4.右边为横表,展示清晰,方便查询
5.很多时候业务表为纵表,但是统计分析需要的结果如右边的横表,这时候就需要用到转置函数了
示例图表:
文章图片
Pivot语法:
-
SELECT ....
-
FROM
-
PIVOT
-
(
-
aggregate-function(
)
-
FOR IN (
, ,..., )
-
) AS
-
WHERE .....
注意:
FOR
这个是不支持表达式的,如果需要,请通过子查询或者视图先预处理。
Pivot
例子1:先构造一个子查询,然后根据CHANNEL列进行转置,源表sales_view里面可能有很多列,不需要列先通过子查询过滤掉再进行转置。
另外转置后的列指定了别名,值是对amount_sold列的汇总。
-
SELECT * FROM
-
(SELECT product, channel, amount_sold
-
FROM sales_view
-
) S PIVOT (SUM(amount_sold)
-
FOR CHANNEL IN (3 AS DIRECT_SALES, 4 AS INTERNET_SALES,
-
5 AS CATALOG_SALES, 9 AS TELESALES))
-
ORDER BY product;
-
PRODUCT DIRECT-_SALES INTERNET_SALES CATALOG_SALES TELESALES
-
---------------------- ------------ -------------- ------------- ---------
-
...
-
Internal 6X CD-ROM 229512.97 26249.55
-
Internal 8X CD-ROM 286291.49 42809.44
-
Keyboard Wrist Rest 200959.84 38695.36 1522.73
-
...
例子2:基于多列进行转置,下面例子是基于channel、quarter两列进行转置
-
SELECT *
-
FROM
-
(SELECT product, channel, quarter, quantity_sold
-
FROM sales_view
-
) PIVOT (SUM(quantity_sold)
-
FOR (channel, quarter) IN
-
((5, '02') AS CATALOG_Q2,
-
(4, '01') AS INTERNET_Q1,
-
(4, '04') AS INTERNET_Q4,
-
(2, '02') AS PARTNERS_Q2,
-
(9, '03') AS TELE_Q3
-
)
-
);
-
PRODUCT CATALOG_Q2 INTERNET_Q1 INTERNET_Q4 PARTNERS_Q2 TELE_Q3
-
------- ---------- ----------- ----------- ----------- -------
-
...
-
Bounce 347 632 954
-
...
-
Smash Up Boxing 129 280 560
-
...
-
Comic Book Heroes 47 155 275
-
...
例子3:对多列的值进行汇总计算,以下是基于channel例进行转置,然后对amount_sold和quantity_sold两列进行合计运算
-
SELECT *
-
FROM
-
(SELECT product, channel, amount_sold, quantity_sold
-
FROM sales_view
-
) PIVOT (SUM(amount_sold) AS sums,
-
SUM(quantity_sold) AS sumq
-
FOR channel IN (5, 4, 2, 9)
-
)
-
ORDER BY product;
-
PRODUCT 5_SUMS 5_SUMQ 4_SUMS 4_SUMQ 2_SUMS 2_SUMQ 9_SUMS 9_SUMQ
-
------------- ------ ------ ------ ------ ------ ------ ------ ------
-
O/S Doc Set English 142780.36 3081 381397.99 8044 6028.66 134
-
O/S Doc Set French 55503.58 1192 132000.77 2782
-
...
Unpivot
unpivot是pivot的相反操作,进行的是列转行
例子1:先看源表结构,for子句指定将(Q1_SUMQ, Q2_SUMQ, Q3_SUMQ, Q4_SUMQ)这4列转置为行,
for子句之前的quantity_sold是4列转置后的列名,
decode还定义了每列转置为行后新标示列的值,这个等下看第2个例子可以看到,也可以在 in 子句后面加 as 指定别名。
UNPIVOT INCLUDE NULLS 指定空值也进行转置,如果是EXCLUDE NULLS 将忽略空值。
-
SELECT *
-
FROM pivotedTable
-
ORDER BY product;
-
PRODUCT Q1_SUMQ Q1_SUMA Q2_SUMQ Q2_SUMA Q3_SUMQ Q3_SUMA Q4_SUMQ Q4_SUMA
-
--------------- ------- ------- ------- -------- ------- -------- ------- ---------
-
1.44MB External 6098 58301.33 5112 49001.56 6050 56974.3 5848 55341.28
-
128MB Memory 1963 110763.63 2361 132123.12 3069 170710.4 2832 157736.6
-
17" LCD 1492 1812786.94 1387 1672389.06 1591 1859987.66 1540 1844008.11
- 【SQL|SQL 行转列 列转行 Oracle转置函数函数pivot、unpivot 解决wm_concat 没有排序】
SELECT product, DECODE(quarter, 'Q1_SUMQ', 'Q1', 'Q2_SUMQ', 'Q2', 'Q3_SUMQ', 'Q3',
-
'Q4_SUMQ', 'Q4') AS quarter, quantity_sold
-
FROM pivotedTable
-
UNPIVOT INCLUDE NULLS
-
(quantity_sold
-
FOR quarter IN (Q1_SUMQ, Q2_SUMQ, Q3_SUMQ, Q4_SUMQ))
-
ORDER BY product, quarter;
-
PRODUCT QUARTER QUANTITY_SOLD
-
------- -- -------------
-
1.44MB External 3.5" Diskette Q1 6098
-
1.44MB External 3.5" Diskette Q2 5112
-
1.44MB External 3.5" Diskette Q3 6050
-
1.44MB External 3.5" Diskette Q4 5848
-
128MB Memory Card Q1 1963
-
128MB Memory Card Q2 2361
-
128MB Memory Card Q3 3069
-
128MB Memory Card Q4 2832
-
...
例子2:转置多列的情况
-
SELECT product, quarter, quantity_sold, amount_sold
-
FROM pivotedTable
-
UNPIVOT INCLUDE NULLS
-
(
-
(quantity_sold, amount_sold)
-
FOR quarter IN ((Q1_SUMQ, Q1_SUMA) AS 'Q1', (Q2_SUMQ, Q2_SUMA) AS 'Q2', (Q3_SUMQ, Q3_SUMA) AS 'Q3', (Q4_SUMQ, Q4_SUMA) AS 'Q4'))
-
ORDER BY product, quarter;
-
PRODUCT QU QUANTITY_SOLD AMOUNT_SOLD
-
----------------------------- -- ------------- ------------
-
1.44MB External 3.5" Diskette Q1 6098 58301.33
-
1.44MB External 3.5" Diskette Q2 5112 49001.56
-
1.44MB External 3.5" Diskette Q3 6050 56974.3
-
1.44MB External 3.5" Diskette Q4 5848 55341.28
-
128MB Memory Card Q1 1963 110763.63
-
128MB Memory Card Q2 2361 132123.12
-
128MB Memory Card Q3 3069 170710.4
-
128MB Memory Card Q4 2832 157736.6
总结,基本上按照语法套用即可,注意将源表非相关列先过滤掉,可是是子查询,也可以是视图。
最后试试解决这个问题吧,看你是否真的懂了!
http://blog.csdn.net/seandba/article/details/72629724
以上内容均来自Oracle11g官方文档,我只是搬运工。。。
Oracle? Database Data Warehousing Guide
11g Release 2 (11.2)
E25554-01
阅读更多收藏
分享
https://blog.csdn.net/seandba/article/details/72730657
https://segmentfault.com/q/1010000009622091?sort=created
Oracle pivot in子查询的疑问 在使用pivot函数进行行转列的时候 in后面接子查询就报错
文章图片
按照oracle的文档,pivot语句中in后面的列如果不固定,只能使用xml格式的返回结果,如:
http://www.oracle-developer.n...
SQL> SELECT *
2FROMpivot_data
3PIVOTXML
4(SUM(sal) FOR deptno IN (ANY));
JOBDEPTNO_XML
--------- ---------------------------------------------------------------------------
ANALYST20 6600 CLERK10 1430 20 2090 30
1045 MANAGER10 2695 20 3272.5 303135
如果不想要xml格式的结果,就只能使用把in之间的内容提前计算出来,动态拼接成sql语句,使用execute immediately动态执行。
- 评论 · 2
- 赞赏
- 编辑
文章图片
邢爱明4.8k
2017-06-05 回答
https://segmentfault.com/q/1010000009622091?sort=created
https://zhidao.baidu.com/question/2203556378984153268.html?qbl=relate_question_0&word=pivot%20for%20in%20%D6%D0%BB%B9%BF%C9%D2%D4%D6%B8%B6%A8%D7%D3%B2%E9%D1%AF
oracle中pivot子查询如何用 50 在oracle中使用pivot函数,看介绍说在in()中可以使用子查询,但是使用子查询执行时报错缺少表达式,请问子查询应该如何使用,是不是pivot不支持子查询,谢谢
文章图片
我来答
分享
举报浏览 6787 次
- 你的回答被采纳后将获得:
- 系统奖励15(财富值+成长值)+难题奖励20(财富值+成长值)+提问者悬赏50(财富值+成长值)
#今日科普# 又到公司年会,有哪些给力的小游戏?
文章图片
chengccy2010
来自电脑网络类芝麻团 2015-05-22
xml 类型的时候可以使用any 关键字和子查询,返回的结果是xml结构的;
select * from (
select times_purchased as "Puchase Frequency", state_code
from customers t
)
pivot xml
(
count(state_code)
for state_code in (select state_code from preferred_states)
)
order by 1
本回答被网友采纳
767
评论
分享
举报
https://zhidao.baidu.com/question/2203556378984153268.html?qbl=relate_question_0&word=pivot%20for%20in%20%D6%D0%BB%B9%BF%C9%D2%D4%D6%B8%B6%A8%D7%D3%B2%E9%D1%AF
推荐阅读
- 代码狂魔|oracle数据库递归查询
- java|50个经典Sql语句
- mysql|面试必备,MySQL InnoDB MVCC机制
- Java毕业设计项目实战篇|Java项目:crm客户关系管理系统(java+SpringBoot+ECharts+Freemarker+Layui+maven+mysql)
- Apply Bug10010310 On Oracle RAC 10.2.0.5
- SQL审核 | SQLE 兼容 MySQL 8.0 测评
- Mysql刷题|【sql】SQL4 查找所有已经分配部门的员工的last_name和first_name以及dept_no
- MongoDB与MySQL有什么区别(功能上和使用上?)
- 《高性能|高性能 MySQL(七)(11个高性能的索引策略)