Oracle 中行列转换问题总结

1)行转列

表结构:STUDENT

create table STUDENT
(
  USER_NAME VARCHAR2(20),
  COURSE    VARCHAR2(20),
  SCORE     FLOAT
)

初始化数据:

INSERT INTO STUDENT(USER_NAME,COURSE,SCORE)VALUES('zhangyue','Enlish',85);
INSERT INTO STUDENT(USER_NAME,COURSE,SCORE)VALUES('zhangyue','Math',75);
INSERT INTO STUDENT(USER_NAME,COURSE,SCORE)VALUES('zhangyue','Chinese',97);
INSERT INTO STUDENT(USER_NAME,COURSE,SCORE)VALUES('zhangyue','Physics',76);
INSERT INTO STUDENT(USER_NAME,COURSE,SCORE)VALUES('heshan','Enlish',95);
INSERT INTO STUDENT(USER_NAME,COURSE,SCORE)VALUES('heshan','Math',67);
INSERT INTO STUDENT(USER_NAME,COURSE,SCORE)VALUES('heshan','Physics',89);
INSERT INTO STUDENT(USER_NAME,COURSE,SCORE)VALUES('heshan','Chinese',79);

初始数据如下图:

 

 如果需要实现如下的查询效果图:

 

这就是最常见的行转列,主要原理是利用decode函数、聚集函数(MAX),结合group by分组实现的,MAX聚集函数也可以用sum、min、avg等其他聚集函数替代。

SQL代码如下:

SELECT t.user_name,
MAX(decode(course,'English',score,0)) AS English,
MAX(decode(course,'Math',score,0)) AS Math,
MAX(decode(course,'Chinese',score,0)) AS Chinese,
MAX(decode(course,'Physics',score,0)) AS Physics
FROM student t 
GROUP BY t.user_name

或者你不是用decode函数

SELECT t.user_name,
MAX(case course when 'English' then score else 0 end) AS English,
MAX(case course when 'Math' then score else 0 end) AS Math,
MAX(case course when 'Chinese' then score else 0 end) AS Chinese,
MAX(case course when 'Physics' then score else 0 end) AS Physics
FROM student t 
GROUP BY t.user_name

2)多行转换成字符串

表结构:tb_name

create table tb_name(id int, remark varchar(2))

初始化数据:

INSERT INTO tb_name VALUES(1,'a');
INSERT INTO tb_name VALUES(1,'b');
INSERT INTO tb_name VALUES(1,'c');
INSERT INTO tb_name VALUES(2,'a');
INSERT INTO tb_name VALUES(2,'d');
INSERT INTO tb_name VALUES(2,'e');
INSERT INTO tb_name VALUES(3,'c');
COMMIT;

初始数据如下图:

如果需要实现如下的查询效果图

wm_concat是oracle 10g引入,以逗号分隔连接列的值

SQL如下:

select id,wm_concat(remark) remark from tb_name t group by id

3)列转行

 表结构:

create table TB_TEST   
(   
  USER_NAME  VARCHAR2(20),   
  English   FLOAT,   
  Math FLOAT,   
  Chinese   FLOAT,
  Physics FLOAT
)  

初始化数据:

insert into TB_TEST (USER_NAME, ENGLISH, MATH, CHINESE, PHYSICS)
values ('zhangyue', 85, 75, 97, 76);

insert into TB_TEST (USER_NAME, ENGLISH, MATH, CHINESE, PHYSICS)
values ('heshan', 95, 67, 79, 89);
COMMIT;

初始数据如下图:

 

如果需要实现如下的查询效果图

我们这里要使用UNION函数 请注意,UNION 内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。

同时,每条 SELECT 语句中的列的顺序必须相同。

SQL语句:

select user_name,'Enlish' course,ENGLISH score from tb_test t UNION
select user_name,'Math' course,MATH score from tb_test t UNION
select user_name,'Chinese' course,CHINESE score from tb_test t UNION
select user_name,'Physics' course,PHYSICS score from tb_test t

4)多列转换成字符串

表结构:

create table TB_COL
(
  ID INTEGER,
  C1 VARCHAR2(2),
  C2 VARCHAR2(2),
  C3 VARCHAR2(2)
)

初始化数据:

insert into tb_col (ID, C1, C2, C3)
values (1, 'c1', 'c2', 'c3');

insert into tb_col (ID, C1, C2, C3)
values (2, 'c4', 'c5', 'c6');

insert into tb_col (ID, C1, C2, C3)
values (3, 'c7', 'c8', 'c9');

COMMIT;

初始数据如下图:

如果需要实现如下的查询效果图

这个比较简单,用||或concat函数可以实现:

SQL语句如下:

select id,c1||','||c2||','||c3 as col from tb_col t

 

以上是个简单的小结,如果有问题请大神们告知,以便我的学习,非常感谢!

posted @ 2013-03-29 13:24  十年半山  阅读(838)  评论(1编辑  收藏  举报