最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Oracle中行列轉(zhuǎn)換兩種實(shí)現(xiàn)方法

 更新時(shí)間:2023年11月25日 08:57:59   作者:龍西  
在Oracle中可以使用多種方法來(lái)實(shí)現(xiàn)行轉(zhuǎn)列和列轉(zhuǎn)行,這篇文章主要給大家介紹了關(guān)于Oracle中行列轉(zhuǎn)換的兩種實(shí)現(xiàn)方法,文中介紹的是用PIVOT和UNPIVOT函數(shù),需要的朋友可以參考下

前言

行列轉(zhuǎn)換是指將行數(shù)據(jù)轉(zhuǎn)換為列數(shù)據(jù),或?qū)⒘袛?shù)據(jù)轉(zhuǎn)換為行數(shù)據(jù)的過(guò)程。這通常使用的辦法是用PIVOT和UNPIVOT函數(shù)來(lái)實(shí)現(xiàn)。這里描述兩種方法分別實(shí)現(xiàn)行列轉(zhuǎn)換?。?!

首先創(chuàng)建表:

學(xué)生表:student;--包括學(xué)生號(hào),姓名,年紀(jì),性別,生日

教師表:teacher;--包括教師編號(hào),姓名

課程表:course;--包括課程編號(hào),課程名稱,對(duì)應(yīng)教師

學(xué)生成績(jī)表:sc;--包括學(xué)生號(hào),課程編號(hào),成績(jī)

創(chuàng)建表的腳本如下:

--學(xué)生 student表
drop table student;
create table student(
sno varchar2(10) primary key,
sname varchar2(20),
sage number(2),
ssex varchar2(5),
birthday date
);
--教師 teacher表
drop table teacher;
create table teacher(
tno varchar2(10) primary key,
tname varchar2(20)
);
--課程 course表
drop table course;
create table course(
cno varchar2(10),
cname varchar2(20),
tno varchar2(20),
constraint pk_course primary key (cno,tno)
);
--學(xué)生成績(jī) sc表
drop table sc;
create table sc(
sno varchar2(10),
cno varchar2(10),
score number(4,2),
constraint pk_sc primary key (sno,cno)
);
/*******初始化學(xué)生表的數(shù)據(jù)******/
insert into student values ('s001','張亍卬',FLOOR(months_between(SYSDATE,date '2000-3-5')/12),'男',date '2000-3-5');
insert into student values ('s002','李殳戔',FLOOR(months_between(SYSDATE,date '2001-2-3')/12),'男',date '2001-2-3');
insert into student values ('s003','吳仝玓',FLOOR(months_between(SYSDATE,date '2002-5-8')/12),'男',date '2002-5-8');
insert into student values ('s004','琴甪',FLOOR(months_between(SYSDATE,date '2000-6-15')/12),'女',date '2000-6-15');
insert into student values ('s005','王讱纊',FLOOR(months_between(SYSDATE,date '2000-8-12')/12),'女',date '2000-8-12');
insert into student values ('s006','李孖伣',FLOOR(months_between(SYSDATE,date '2001-9-20')/12),'男',date '2001-9-20');
insert into student values ('s007','劉辿吒',FLOOR(months_between(SYSDATE,date '2002-10-5')/12),'男',date '2002-10-5');
insert into student values ('s008','蕭?cǎi)道?,FLOOR(months_between(SYSDATE,date '2003-6-1')/12),'女',date '2003-6-1');
insert into student values ('s009','陳閆邠邡',FLOOR(months_between(SYSDATE,date '2001-1-15')/12),'女',date '2001-1-15');
insert into student values ('s010','陳芃伋',FLOOR(months_between(SYSDATE,date '2001-1-9')/12),'女',date '2001-1-9');
commit;
/******************初始化教師表***********************/
insert into teacher values ('t001', '龔陽(yáng)');
insert into teacher values ('t002', '諶燕');
insert into teacher values ('t003', '武明星');
commit;
/***************初始化課程表****************************/
insert into course values ('c001','J2SE','t002');
insert into course values ('c002','Java Web','t001');
insert into course values ('c003','SSH','t001');
insert into course values ('c004','Oracle','t001');
insert into course values ('c005','SQL SERVER 2005','t003');
insert into course values ('c006','C#','t003');
insert into course values ('c007','JavaScript','t003');
insert into course values ('c008','DIV+CSS','t001');
insert into course values ('c009','PHP','t003');
insert into course values ('c010','EJB3.0','t002');
commit;
/***************初始化成績(jī)表***********************/
insert into sc values ('s001','c001',78);
insert into sc values ('s002','c001',80);
insert into sc values ('s003','c001',81);
insert into sc values ('s004','c001',60);
insert into sc values ('s001','c002',82);
insert into sc values ('s002','c002',72);
insert into sc values ('s003','c002',81);
insert into sc values ('s001','c007',88);
insert into sc values ('s001','c010',73);
insert into sc values ('s002','c003',69);
insert into sc values ('s002','c008',92);
insert into sc values ('s002','c009',81);
insert into sc values ('s002','c007',85);
insert into sc values ('s002','c010',75);
insert into sc values ('s005','c001',63);
insert into sc values ('s005','c002',96);
insert into sc values ('s005','c007',75);
insert into sc values ('s005','c010',72);
insert into sc values ('s006','c001',72);
insert into sc values ('s007','c001',61);
insert into sc values ('s008','c001',92);
insert into sc values ('s009','c001',58);
insert into sc values ('s010','c001',85);
insert into sc values ('s002','c004',80);
insert into sc values ('s002','c005',70);
insert into sc values ('s002','c006',60);
commit;

一、行轉(zhuǎn)列(一)

使用case when/decode+聚合函數(shù)+group by的方法實(shí)現(xiàn)行轉(zhuǎn)列;

把sc表進(jìn)行行轉(zhuǎn)列查詢出每個(gè)學(xué)生每門課程的成績(jī):

原sc表:

SELECT * FROM sc;--學(xué)生成績(jī)表

執(zhí)行結(jié)果展示其中一部分:

 此時(shí)要對(duì)cno課程編號(hào)進(jìn)行行轉(zhuǎn)列:

select sno,sum(case cno when 'c001' then score end) c001,
           sum(case cno when 'c002' then score end) c002,
           sum(case cno when 'c003' then score end) c003,
           sum(case cno when 'c004' then score end) c004,
           sum(case cno when 'c005' then score end) c005,
           sum(case cno when 'c006' then score end) c006,
           sum(case cno when 'c007' then score end) c007,
           sum(case cno when 'c008' then score end) c008,
           sum(case cno when 'c009' then score end) c009,
           sum(case cno when 'c0010' then score end) c0010
from sc
group by sno  
order by sno;

執(zhí)行結(jié)果:

展示的為每個(gè)學(xué)生他的每一門課程成績(jī);

總結(jié):

要求把查詢的哪一列轉(zhuǎn)成列名就放在case后面,并把它的列中值進(jìn)行分類放在when后面;

比如學(xué)生成績(jī)表總共就三列(學(xué)生號(hào),課程編號(hào),學(xué)生成績(jī)),我們要查詢每個(gè)學(xué)生的每科成績(jī)展示,就需要對(duì)課程編號(hào)cno進(jìn)行分類轉(zhuǎn)換,因此把課程編號(hào)cno放在case后面,然后把課程編號(hào)cno中所包含的所有值進(jìn)行分類,即全部課程科目c001--c0010,分類放在when的后面?。?/p>

要把哪一列內(nèi)容放在列中值中就放在then 后面;

意思就是我們最后要看的結(jié)果值,比如對(duì)應(yīng)上面查詢,要查看的是學(xué)生成績(jī)score,此時(shí)就把學(xué)生成績(jī)score放在then的后面即可。

這種辦法可以實(shí)現(xiàn)我們對(duì)需求的解決實(shí)現(xiàn),但是使用比較麻煩,可能會(huì)理解錯(cuò)誤,而且代碼語(yǔ)句寫的比較多,因此可以換種方法來(lái)更簡(jiǎn)單實(shí)現(xiàn)行轉(zhuǎn)列?。?!

二、行轉(zhuǎn)列(二) 

使用PIVOT函數(shù),可以將行數(shù)據(jù)轉(zhuǎn)換為列數(shù)據(jù),并且可以在同一查詢中匯總和篩選數(shù)據(jù)。

基本語(yǔ)法格式如下:

PIVOT(被聚合的列 FOR 行轉(zhuǎn)列的列 in(列中值1,列中值2...))
 
select *
from  表
pivot (聚合函數(shù)(被聚合的列) for 行轉(zhuǎn)列的列 in (列中值1,,列中值2植..))

批注:

被聚合的列:變成列中值的列;

行轉(zhuǎn)列的列:由列中值變?yōu)榱忻牧?; 

列中值1,列中值2..:新增加的列名(即為行轉(zhuǎn)列的列中的列中值)就是列中值1,列中值2...。

備注:被聚合的列要加聚合函數(shù)。

或者另一種理解:

SELECT *
FROM (SELECT column1, column2, column3 FROM table_name)
PIVOT (aggregate_function(column2) 
       FOR column1 IN ('value1' AS alias1, 'value2' AS alias2, ...));

其中,PIVOT中的column1是要轉(zhuǎn)換為列的列,column2是要匯總的列,alias是列的別名。

那么此時(shí)“把sc表行轉(zhuǎn)列查詢每個(gè)學(xué)生每門課程的成績(jī)”可寫為:

select *
from sc
pivot(sum(score) for cno in('c001' c001,'c002' c002,'c003' c003,'c004' c004,
                'c005' c005,'c006' c006,'c007' c007,'c008' c008,'c009' c009,'c010' c010))
order by sno;

其中,as可加可不加,對(duì)于列中值一定要加單引號(hào)。同時(shí)運(yùn)行結(jié)果是和之前的一致。如圖所示:

使用PIVOT函數(shù)時(shí),需要注意以下幾點(diǎn):

  • PIVOT函數(shù)必須在FROM子句中使用,因此需要將原始查詢包裝在一個(gè)子查詢中。
  • aggregate_function是要應(yīng)用于column2的聚合函數(shù),可以是SUM、AVG、COUNT、MAX、MIN等。
  • FOR子句指定要在新列中顯示的值。在IN子句中指定這些值,并在別名中指定新列的名稱。

三、列轉(zhuǎn)行(一)

使用union all方法實(shí)現(xiàn)列轉(zhuǎn)行;

比如:有一張員工表emp,請(qǐng)用一條sql顯示如下格式

  ENPNO  KEY     VALUE 
  7369  ENAME    SMITH
  7369  JOB      CLERK
  7369  MGR      7902

先看原員工表格式:

select * from emp;

 通過(guò)對(duì)比發(fā)現(xiàn)是將原表中的列和其對(duì)應(yīng)值轉(zhuǎn)換為行式展現(xiàn),同時(shí)為其定義了新的列名分別為ENPNO 、KEY 、VALUE 。那么用union all的方式實(shí)現(xiàn)的語(yǔ)句為:

select * from 
  (select empno,'ENAME' KEY,ENAME VALUE FROM EMP 
  UNION ALL
  select empno,'JOB' KEY,TO_CHAR(JOB) VALUE FROM EMP
  UNION ALL
  select empno,'MGR' KEY,TO_CHAR(MGR) VALUE FROM EMP
  UNION ALL
  select empno,'HIREDATE' KEY,TO_CHAR(HIREDATE) VALUE FROM EMP
  UNION ALL
  select empno,'SAL' KEY,TO_CHAR(SAL) VALUE FROM EMP
  UNION ALL
  select empno,'COMM' KEY,TO_CHAR(COMM) VALUE FROM EMP
  UNION ALL
  select empno,'DEPTNO' KEY,TO_CHAR(DEPTNO) VALUE FROM EMP)
WHERE EMPNO=7369;

簡(jiǎn)單理解為:查詢?cè)搯T工編號(hào)對(duì)應(yīng)的每一條列信息,對(duì)列中值進(jìn)行格式轉(zhuǎn)換統(tǒng)一,然后使用union all進(jìn)行并集為一個(gè)數(shù)據(jù)集合作為參考表,最后加判斷條件完成列轉(zhuǎn)換。那么看下這種方式的運(yùn)行結(jié)果:

通過(guò)改圖發(fā)現(xiàn)確實(shí)已經(jīng)完成了目的需求的格式轉(zhuǎn)換。不過(guò)此方法同樣比較繁瑣,代碼量也比較多,所以可以換另外一種方法實(shí)現(xiàn)同樣的效果。

四、列轉(zhuǎn)行(二)

UNPIVOT函數(shù)可以將列數(shù)據(jù)轉(zhuǎn)換為行數(shù)據(jù)?;菊Z(yǔ)法如下:

unpivot 列轉(zhuǎn)行自動(dòng)去空 如果要留住空值 在unpivot 后加上 include nulls
 
unpivot(被聚合的列的新列名 for  列轉(zhuǎn)行的列的新列名 in (字段1,字段2...))

被聚合的列的新列名:指的是目標(biāo)結(jié)果集的列名,按照目標(biāo)結(jié)果集來(lái)填寫,即原來(lái)聚合的數(shù)據(jù)如這里的nums,列轉(zhuǎn)行之前的列中值放在取了新名字的這個(gè)列中;

列轉(zhuǎn)行的列的新列名:指的是要列轉(zhuǎn)行的列名的集合新名字,既創(chuàng)建一個(gè)新的列來(lái)存儲(chǔ)要列轉(zhuǎn)行的列,如這里的name,他的列中值在列傳行之前為原視圖的多個(gè)列;

字段1,字段2...:指的是要列轉(zhuǎn)行的列名,既為要放到列轉(zhuǎn)行的列的新列名里的列中值,就是列轉(zhuǎn)行之前視圖的多個(gè)列。

完整格式:

SELECT *
FROM table_name
UNPIVOT (column3 FOR column1 IN (column2, column3, ...));

column1是要轉(zhuǎn)換為行的列,column2和column3是要轉(zhuǎn)換的列。

那么此時(shí)使用UNPIVOT函數(shù)完成上個(gè)問(wèn)題的列轉(zhuǎn)行方法就可以寫為:

select *
from (SELECT empno,ENAME,JOB,
             TO_CHAR(MGR) MGR,
             TO_CHAR(HIREDATE) HIREDATE,
             TO_CHAR(SAL) SAL,
             TO_CHAR(COMM) COMM,
             TO_CHAR(DEPTNO) DEPTNO
      FROM EMP
      WHERE EMPNO=7369)
unpivot include nulls(VALUE for KEY IN(ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO));

這里在列轉(zhuǎn)行時(shí)對(duì)表中每一列做了格式統(tǒng)一,最后運(yùn)行結(jié)果和第一種方法一樣。如圖所示:

使用UNPIVOT函數(shù)時(shí),需要注意以下幾點(diǎn):

  • UNPIVOT函數(shù)必須在FROM子句中使用,因此需要將原始查詢包裝在一個(gè)子查詢中。
  • FOR子句指定要轉(zhuǎn)換為行的列。
  • IN子句指定要轉(zhuǎn)換的列。

總結(jié)

到此這篇關(guān)于Oracle中行列轉(zhuǎn)換兩種實(shí)現(xiàn)方法的文章就介紹到這了,更多相關(guān)Oracle行列轉(zhuǎn)換內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

宣汉县| 蒙城县| 股票| 双流县| 陆川县| 蛟河市| 屏南县| 呼图壁县| 丹凤县| 龙门县| 巢湖市| 罗平县| 宜州市| 滦南县| 肃北| 洛隆县| 正定县| 南川市| 西平县| 抚远县| 凌海市| 兴宁市| 海口市| 治县。| 临沧市| 桂平市| 历史| 东丽区| 靖江市| 道孚县| 临海市| 宜都市| 衡阳市| 武穴市| 景泰县| 会宁县| 盱眙县| 集贤县| 河西区| 塔河县| 密山市|