Oracle 行列转换
1、 固定列数的行列转换
如
如
student | subject | grade |
student1 | 语文 | 80 |
student1 | 数学 | 70 |
student1 | 英语 | 60 |
Student2 | 语文 | 90 |
Student2 | 数学 | 80 |
Student2 | 英语 | 100 |
转换为
student | 语文 | 数学 | 英语 |
student1 | 80 | 70 | 60 |
Student2 | 90 | 80 | 100 |
语句如下:
create table tb_chengji (student varchar2(20),subject varchar2(20), grade number);
select student,
sum(case subject when '语文' then grade end) "语文",
sum(case subject when '数学' then grade end) "数学",
sum(case subject when '英语' then grade end) "英语",
sum(grade) "总分"
from tb_chengji
group by student;
或者
select student,
sum(decode(subject,'语文',grade,null)) "语文",
sum(decode(subject,'数学',grade,null)) "数学",
sum(decode(subject,'英语',grade,null)) "英语",
sum(grade) "总分"
from tb_chengji
group by student;
2、 不定列行列转换
如
c1 c2
--- -----------
1 我
1 是
如
c1 c2
--- -----------
1 我
1 是
1 谁
2 知
2 道
3 不
……
转换为
1 我是谁
2 知道
3 不
这一类型的转换可以借助于PL/SQL来完成,这里给一个例子
2 知
2 道
3 不
……
转换为
1 我是谁
2 知道
3 不
这一类型的转换可以借助于PL/SQL来完成,这里给一个例子
create table ttt (c1 number,c2 varchar2(10) );
select * from ttt;
create or replace function get_c2(tmp_c1 number)
return varchar2
is
col_c2 varchar2(4000);
begin
for cur in (select c2 from ttt where c1=tmp_c1) loop
col_c2 := col_c2||cur.c2;
end loop;
col_c2 := rtrim(col_c2,1);
return col_c2;
end;
select distinct c1 ,get_c2(c1) cc2 from ttt
order by c1;
或者不用pl/sql,利用分析函数和 CONNECT_BY 实现:
select c1, substr (max (sys_connect_by_path (c2, ';')), 2) name
或者不用pl/sql,利用分析函数和 CONNECT_BY 实现:
select c1, substr (max (sys_connect_by_path (c2, ';')), 2) name
from (select c1, c2, rn, lead (rn) over (partition by c1 order by rn) rn1
from (select c1, c2, row_number () over (order by c2) rn
from ttt))
start with rn1 is null
connect by rn1 = prior rn
group by c1;
3、列数不固定(交叉表行列转置)
这种是比较麻烦的一种,需要借助pl/sql:
原始数据:
CLASS1 CALLDATE CALLCOUNT
1 2005-08-08 40
1 2005-08-07 6
2 2005-08-08 77
3 2005-08-09 33
3 2005-08-08 9
3 2005-08-07 21
转置后:
CALLDATE CallCount1 CallCount2 CallCount3
-
----------- ---------- ---------- ----------
2005-08-09 0 0 33
2005-08-08 40 77 9
2005-08-07 6 0 21
试验如下:
1). 建立测试表和数据
CREATE TABLE t22(
2005-08-09 0 0 33
2005-08-08 40 77 9
2005-08-07 6 0 21
试验如下:
1). 建立测试表和数据
CREATE TABLE t22(
class1 VARCHAR2(2 BYTE),
calldate DATE,
callcount INTEGER
);
INSERT INTO t22(class1, calldate, callcount)
VALUES ('1', TO_DATE ('08/08/2005', 'MM/DD/YYYY'), 40);
INSERT INTO t22(class1, calldate, callcount)
VALUES ('1', TO_DATE ('08/07/2005', 'MM/DD/YYYY'), 6);
INSERT INTO t22(class1, calldate, callcount)
VALUES ('2', TO_DATE ('08/08/2005', 'MM/DD/YYYY'), 77);
INSERT INTO t22(class1, calldate, callcount)
VALUES ('3', TO_DATE ('08/09/2005', 'MM/DD/YYYY'), 33);
INSERT INTO t22(class1, calldate, callcount)
VALUES ('3', TO_DATE ('08/08/2005', 'MM/DD/YYYY'), 9);
INSERT INTO t22(class1, calldate, callcount)
VALUES ('3', TO_DATE ('08/07/2005', 'MM/DD/YYYY'), 21);
COMMIT ;
select calldate,
nvl(max(case when class1 isnull的用法= 1 then callcount end ),0) a1,
nvl(max(case when class1 = 2 then callcount end ) ,0) a2,
nvl(max(case when class1 = 3 then callcount end ),0) a3
from t22
group by calldate
order by calldate desc;
CALLDATE CallCount1 CallCount2 CallCount3
------------ ---------- ---------- ----------
------------ ---------- ---------- ----------
2005-8-9 0 0 33
2005-8-8 40 77 9
2005-8-7 6 0 21
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论