重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
/*
成都创新互联坚持“要么做到,要么别承诺”的工作理念,服务领域包括:网站建设、网站制作、企业官网、英文网站、手机端网站、网站推广等服务,满足客户于互联网时代的锦屏网站设计、移动媒体设计的需求,帮助企业找到有效的互联网解决方案。努力成为您成熟可靠的网络建设合作伙伴!
在实际使用sql工作中总会碰到将某一列的值放到标题中显示 就是总说的行列转换或者互换
比如有如下数据:
ID NAME KECHENG CHENGJI
a 语文
a 数学
b 语文
b 数学
c 语文
c 数学
那末我要求显示的结果是:
NAME YUWEN SHUXUE
a
也就是说把课程这一列放到行上显示 把成绩按照课程分配到相对应的行
我只介绍 中简单易用的方法 使用游标或者建立临时表的方法就不介绍了 效率很慢 不易理解
首先建立表:
*/
create table fzq
(
id varchar( )
name varchar( )
kecheng varchar( )
chengji varchar( )
);
插入数据:
insert into fzq values ( a 语文 );
insert into fzq values( a shuxue );
insert into fzq values ( b yuwen );
insert into fzq values ( b shuxu );
insert into fzq values ( c yuwen );
insert into fzq values ( c shuxu );
/*首先使用union 如果课程这列有多个值 那么脚本的代码就很长了 */
select name sum(yuwen) yuwen sum(shuxue) shuxue from
(
select name chengji yuwen shuxue from fzq
where kecheng= yuwen union
select name yuwen chengji shuxue
from fzq
where kecheng= shuxue
) aaa
group BY name;
/*执行结果:
NAME YUWEN SHUXUE
a
b
c
*/
/*
其次是用case 这种方法代码比较短 适合列值很多的情况
*/
select name sum(case kecheng when yuwen then chengji end) yuwen
sum(case kecheng when shuxue then chengji end) shuxue
from fzq
group by name;
/*执行结果:
NAME YUWEN SHUXUE
a
b
c
所有例子在oracle中测试 sql server没有测试 请根据实际情况修改
*/
select name sum(decode(kecheng 语文 chengji null)) 语文
sum(decode(kecheng 数学 chengji null)) 数学
sum(decode(kecheng 英语 chengji null)) 英语
from fzq
lishixinzhi/Article/program/Oracle/201311/18036
第二种效率高,首先筛选条件少,二不做汇总时数据量也明显比第一种的少,三不用自连接
固定列数的行列转换如
student subject grade
---------------------------
student1 语文 80
student1 数学 70
student1 英语 60
student2 语文 90
student2 数学 80
student2 英语 100
转换为
语文 数学 英语
student1 80 70 60
student2 90 80 100
语句如下:
select student,sum(decode(subject,'语文', grade,null)) "语文",
sum(decode(subject,'数学', grade,null)) "数学",
sum(decode(subject,'英语', grade,null)) "英语"
from table
group by student
2、不定列行列转换如
c1 c2
--------------
1 我
1 是
1 谁
2 知
2 道
3 不
......
转换为
1 我是谁
2 知道
3 不
这一类型的转换必须借助于PL/SQL来完成,这里给一个例子
CREATE OR REPLACE FUNCTION get_c2(tmp_c1 NUMBER)
RETURN VARCHAR2
IS
--用于返回值
Col_c2 VARCHAR2(4000);
BEGIN
FOR cur IN (SELECT c2 FROM t WHERE c1=tmp_c1) LOOP
Col_c2 := Col_c2||cur.c2;
END LOOP;
Col_c2 := rtrim(Col_c2,1);
RETURN Col_c2;