基本思路:对每班学生排序,根据序号构造列名,拼接动态sql
创新互联公司是一家专注于网站建设、网站制作与策划设计,浮山网站建设哪家好?创新互联公司做网站,专注于网站建设十年,网设计领域的专业建站公司;建站业务涵盖:浮山等地区。浮山做网站价格咨询:18982081108
--测试数据
create table
("学生" varchar2(10)
,"学号" varchar2(10)
,"班级" varchar2(10)
);
insert into "表A"
select '张三','100','一班' from dual union all
select '李四','101','二班' from dual union all
select '王五','102','一班' from dual union all
select '赵六','103','三班' from dual union all
select '李二','104','二班' from dual
--动态拼接Pivot
declare
sqlstr varchar2(8000):='';
begin
--构造类似于 '学号1','学号2',... 的字符串
for x in (
select distinct row_number() over (partition by "班级" order by "学号") seq
from "表A" order by seq ) loop
sqlstr := sqlstr || ',''' || '学号' ||to_char(x.seq)||'''';
end loop;
sqlstr:=substr(sqlstr,2,length(sqlstr)-1);
--将前面构造的字符串放入Pivot语句中
sqlstr:='
select * from (
select "学号","班级", ''学号''|| to_char(
row_number() over (partition by "班级" order by "学号")) seq
from "表A") t
pivot(
max("学号")
for seq in ('||sqlstr||')
)';
--dbms_output.put_line(sqlstr);
--将查询结果放入临时视图中
sqlstr := 'CREATE OR REPLACE VIEW tmp_result AS '|| sqlstr;
--dbms_output.put_line(sqlstr);
execute immediate sqlstr;
end;
--查看结果
select * from tmp_result;
结果如下:
可以使用wm_concat()函数;
下面是我做的一个例子,可以参考下,当然具体语法可以百度,也可以去官方文档查:
SCOTT@ ysdb1show user
USER is "SCOTT"
SCOTT@ ysdb1create table test_concat(id number(5),name varchar2(10));
Table created.
SCOTT@ ysdb1insert into test_concat values(1,'a');
1 row created.
SCOTT@ ysdb1insert into test_concat values(1,'b');
1 row created.
SCOTT@ ysdb1insert into test_concat values(1,'c');
1 row created.
SCOTT@ ysdb1insert into test_concat values(2,'q');
1 row created.
SCOTT@ ysdb1insert into test_concat values(2,'w');
1 row created.
SCOTT@ ysdb1insert into test_concat values(2,'e');
1 row created.
SCOTT@ ysdb1insert into test_concat values(2,'f');
1 row created.
SCOTT@ ysdb1select * from test_concat;
ID NAME
---------- ----------
1 a
1 b
1 c
2 q
2 w
2 e
2 f
7 rows selected.
SCOTT@ ysdb1select wm_concat(name) from test_concat;
WM_CONCAT(NAME)
--------------------------------------------------------------------------------
a,b,c,q,w,e,f
SCOTT@ ysdb1select id,wm_concat(name) from test_concat group by id;
ID WM_CONCAT(NAME)
---------- --------------------------------------------------------------------------------
1 a,c,b
2 q,f,e,w
INSERT INTO 新表 (SELECT ID, '呼吸系统疾病' FROM 原表 WHERE 呼吸系统疾病有无 = 1 UNION SELECT ID, '消化系统疾病' FROM 原表 WHERE 消化系统疾病有无 = 1
UNION SELECT ID, '循环系统疾病' FROM 原表 WHERE 循环系统疾病有无 = 1)
如果使用行转列,还得使用merge into,还不如上面的语句清晰。
Oracle 11g 行列互换 pivot 和 unpivot 说明在Oracle 11g中,Oracle 又增加了2个查询:pivot(行转列) 和unpivot(列转行)
参考:、 一下,网上有一篇比较详细的文档:
pivot 列转行
测试数据 (id,类型名称,销售数量),案例:根据水果的类型查询出一条数据显示出每种类型的销售数量。
?
123456789
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);
分组查询 (当然这是不符合查询一条数据的要求的)
?
1
select name, sum(nums) nums from demo group by name
行转列查询
?
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函数,等同于下列语句,只是代码比较长,容易理解
?
12
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='芒果');
unpivot 行转列
顾名思义就是将多列转换成1列中去
案例:现在有一个水果表,记录了4个季度的销售数量,现在要将每种水果的每个季度的销售情况用多行数据展示。
创建表和数据
?
1234567
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
列转行查询
?
1
select id , name, jidu, xiaoshou from Fruit unpivot (xiaoshou for jidu in (q1, q2, q3, q4) )
注意: unpivot没有聚合函数,xiaoshou、jidu字段也是临时的变量