Oracle 分析函数


DROP TABLE DEPT;
CREATE TABLE DEPT (
       DID VARCHAR2(10) PRIMARY KEY,
       DEPTNO VARCHAR2(30) NOT NULL,
       DNAME VARCHAR2(30) NOT NULL,
       D_PART VARCHAR2(30),
       MIN_SAR VARCHAR2(30),
       MAX_SAR VARCHAR2(30)
       );
INSERT INTO DEPT VALUES(1,'000001','DEPT1','A','2000','5000');
INSERT INTO DEPT VALUES(2,'000002','DEPT2','A','2000','5000');
INSERT INTO DEPT VALUES(3,'000003','DEPT3','A','4000','6000');
INSERT INTO DEPT VALUES(4,'000004','DEPT4','B','4000','7000');
INSERT INTO DEPT VALUES(5,'000005','DEPT5','B','5000','8000');
INSERT INTO DEPT VALUES(6,'000006','DEPT6','B','2000','9000');
COMMIT;

DROP TABLE DEPT_USER;  
CREATE TABLE DEPT_USER(
       U_ID VARCHAR2(10) PRIMARY KEY,
       D_DID VARCHAR2(10),
       D_UNAME VARCHAR2(30) NOT NULL,
       D_SAR VARCHAR2(30)
       );
INSERT INTO DEPT_USER VALUES(1,1,'JONES','5000');
INSERT INTO DEPT_USER VALUES(2,1,'IRIS','5000');
INSERT INTO DEPT_USER VALUES(3,3,'SIMIDA','6000');
INSERT INTO DEPT_USER VALUES(4,5,'TOM','7000');
INSERT INTO DEPT_USER VALUES(5,5,'SUSAN','8000');
INSERT INTO DEPT_USER VALUES(6,5,'JANE','9000');
INSERT INTO DEPT_USER VALUES(7,NULL,'TIM','9000');
COMMIT;       
 
DROP TABLE EMP1;       
CREATE TABLE EMP1(
       U_ID VARCHAR2(10) PRIMARY KEY,
       DID VARCHAR2(10),
       DEPTNO VARCHAR2(30),
       D_UNAME VARCHAR2(30) NOT NULL,
       SAR VARCHAR2(30),
       SAl VARCHAR2(30),
       SEX VARCHAR2(30),
       JOB VARCHAR2(30)
       );   
INSERT INTO EMP1 VALUES(1,1,'000001','JONES','500','4500','B','厨师');
INSERT INTO EMP1 VALUES(2,2,'000002','IRIS','650','6500','B','助理');
INSERT INTO EMP1 VALUES(3,2,'000003','SIMIDA','660','6600','B','工程师');
INSERT INTO EMP1 VALUES(4,3,'000003','TOM','780','7800','G','工程师');
INSERT INTO EMP1 VALUES(5,3,'000003','SUSAN','850','850','G','助理');
INSERT INTO EMP1 VALUES(6,3,'000003','JANE','800','800','G','经理');
INSERT INTO EMP1 VALUES(7,NULL,'','TIM','9000','9000','G','助理');
INSERT INTO EMP1 VALUES(8,9,'000009','TIM','6000','6000','G','经理');
COMMIT; 

--分析函数
/**
1、over(
(1)、partition by:分组
(2)、order by:排序
(3)、rows/range ..between number/unbounded preceding and number/unbounded following  and(窗口,有group by才能用)
)
2、排序函数(从一开始向N递增)

(1)、row_number():
(2)、rank()
(1)、dense_rank()

3、first_value()、last_value()--first_value第一個值、last_value最後一個值--可用於求最值
4、lag/lead(列名,偏移位数,超出表默认值)
5、group by rollup/cube(a,b,c)
**/

/**
--排序函数
row_number():123
rank():112
dense_rank():113
**/


select d.rn,d.* from 
(select a.*,row_number() over(partition by d_part order by did) rn from dept a )d 
order by did;

select a.*,
row_number() over(order by max_sar desc) rn,
rank() over(order by max_sar desc) rk,
dense_rank() over(order by max_sar desc)dr from dept a


--偏移lag、lead
select a.*,
lag(min_sar,1,0) over(partition by d_part order by max_sar) 向下偏移,
lead(max_sar,1,10000) over(partition by d_part order by max_sar) 向上偏移
from dept a


--第一个值,最后一个值
select a.*,
first_value(max_sar) over(partition by d_part order by max_sar ) fv,
last_value(max_sar) over(partition by d_part order by max_sar  ) lv
from dept a


--获取工资比例  ratio_to_report
select d.*,round(ratio_to_report(d_sar)over(partition by d_did),2)占当前部门比例 
from dept_user d; 

--ntile函数分组
select d.*, ntile(4) over(order by did) as 组 from emp1 d--必須要有order by 條件

--rank/range
select d.*, sum(d_sar) 
over(partition by d_did order by U_ID rank between 3 preceding and 3 following) as 组 --上下3行的值的總和
from dept_user d

select d.*, avg(d_sar) 
over(partition by d_did order by d_sar rank between current row  and 3 following) as 组--當前組當前行到下3行的平均值
from dept_user d 

select e.*,avg(sar)
over(partition by did order by sar range between current row  and 4300 following) as 值--當前組當前值到下浮動為4300的平均值
from emp1 e; 

select e.*,avg(sar)
over(partition by did order by sar range between 4400 preceding and 4500 following) as 值--上浮動4400和下浮動4500的值的平均值
from emp1 e; 


--返回最值所在行的数据 
--first_value第一個值、last_value最後一個值
select d.*,topsar from (select first_value(d_uname) over(partition by d_did) as topsar 
from dept_user 
where d_sar in (select max(d_sar)from dept_user) order by u_id,d_sar desc)a,dept_user d;

select dept_user.*,d_uname  as topsar 
from dept_user 
where d_sar in (select max(d_sar)from dept_user)order by u_id,d_sar desc;

with a as
(select d.*, max(d_sar) over(partition by d_did)最高工资 from dept_user d), 
b as
(select d.*, rank() over(partition by d_did order by d_sar) rk from dept_user d)
select b.* from b where rk=1;

select d.*,first_value(d_uname)over(partition by d_did order by d_sar desc,d_uname desc) from dept_user d;

select d.*,max(d_uname) over(partition by d_did order by d_sar desc)部门工资最高的人 from 
 dept_user d;

--獲取各個部門最高工資的人的排序
select * from dept_user;
select d_did,
LISTAGG(d_uname,',') 
within group(order by d_sar desc)
over(partition by d_did) 工作最高的人 from dept_user  order by d_sar;
--eg:
SELECT did,sar,listagg(D_UNAME,',')
WITHIN GROUP(ORDER BY sar DESC)
OVER(PARTITION BY did) FROM emp1;
 

--獲取各個部門最高工資的人(單個)
select u_id,d_did,
max(d_uname) keep(dense_rank first order by d_sar)
over(partition by d_did) 工作最高的人 from dept_user;

select did,d_uname,
max(d_uname) keep(dense_rank first order by sar)
over(partition by did) 工作最高的人 from emp1;


--獲取某個部門最高工資的人(多個)
create or replace view three_dept_sqr as select d.*, rank() over(partition by d_did order by d_sar desc) rk from dept_user d where d_did=5;
select * from three_dept_sqr;
with x1 as
(select listagg(d_uname,',')within group(order by rk)最高工資的人 from three_dept_sqr ds where rk=1)
select ds.*,最高工資的人 from three_dept_sqr ds,x1 

--獲取各個部門最高工資的人(多個)
with 
x1 as 
(select d.*, rank() over(partition by d_did order by d_sar desc) rk from dept_user d),
x2 as
(select d_did,listagg(d_uname,',')within group(order by rk)最高工資的人 from x1 where rk=1 group by d_did)
select x1.*,最高工資的人 from x1,x2 where x1.d_did=x2.d_did  
--eg:
WITH x1 AS
(SELECT e.*,dense_rank()OVER(PARTITION BY did ORDER BY sar desc)rk FROM emp1 e),
x2 AS
(SELECT did,listagg(d_uname,',')WITHIN GROUP(ORDER BY sar)FROM x1 WHERE rk=1 GROUP BY did)
SELECT * FROM x1,x2 WHERE x1.did=x2.did ORDER BY sar DESC; 


-----------------------行列裝換begin------------------

--行转列(case..when..then\pivot)
select d_uname,
sum(case when d_did=1 then d_sar end) as 部门2的工资,
  sum(case when d_did=3 then d_sar end) as 部门3的工资,
   sum(case when d_did=5 then d_sar end) as 部门4的工资
 from dept_user 
 group by d_uname;
 
 --pivot只能对一个条件有效,需要同时转换2个或以上条件时需要用case..when..then
 select * from(select d_uname,d_sar,d_did from dept_user)
 pivot(sum(d_sar) as s for d_did in (1 as b1,3 as b3,5 as b5));
  


--列转行(union all\unpivot)
with x1 as
 (select * from(select d_uname,d_sar,d_did from dept_user)
 pivot(sum(d_sar) as s for d_did in (1 as b1,3 as b3,5 as b5)))
 select * from x1 unpivot(d_sar for d_did in(b1_s,b3_s,b5_s));

--sept1:
select job, 
sum(case when deptno='000001' then sal end) as 部門000001總工資,
sum(case when deptno='000003' then sal end) as 部門000003總工資,
sum(case when deptno='000005' then sal end) as 部門000005總工資
from emp1 group by job;

--sept2: 
 create or replace view p_view
 as
 select * from emp1
 pivot(sum(sal) as 總工資 for deptno in('000001' 部門000001,'000003' 部門000003,'000005' 部門000005));

--sept3: 
 select * from p_view
 unpivot(sal for deptno IN(部門000001_總工資,部門000003_總工資,部門000005_總工資 ));
 
-----------------------行列裝換end------------------

CREATE OR REPLACE  VIEW v_emp1 AS( SELECT  * FROM (SELECT decode(sex,'B','男','G','女') AS 性別,did,U_ID FROM emp1) 
PIVOT(COUNT(U_ID) FOR did IN(1 AS 部門一,2 AS 部門二,3 AS 部門三)));
SELECT * FROM v_emp1;

SELECT * FROM v_emp1
unpivot(人數 FOR 部門 IN(部門一,部門二,部門三));

SELECT did,SUM(CASE WHEN sex='B' THEN 1 ELSE 0 END) 男,
        SUM(CASE WHEN sex='G' THEN 1 ELSE 0 END) 女 FROM emp1 GROUP BY did;
        
------------纍計

 create table User_Salary (UserName varchar(200), Month varchar(20), Salary int)

  insert into User_Salary (UserName,Month,Salary ) values('AAA','2010/12',1000);
  insert into User_Salary (UserName,Month,Salary ) values('AAA','2011/01',2000);
  insert into User_Salary (UserName,Month,Salary ) values('AAA','2011/02',3000);
  insert into User_Salary (UserName,Month,Salary ) values('AAA','2011/03',1000);
  insert into User_Salary (UserName,Month,Salary ) values('AAA','2011/04',2000);
  insert into User_Salary (UserName,Month,Salary ) values('AAA','2011/05',3000);


  SELECT USERNAME,MONTH,SALARY, (
         SELECT SUM(SALARY) 
         FROM 
              USER_SALARY I
          WHERE  I.MONTH<=O.MONTH
         )CUMMULATION
 FROM USER_SALARY O
 ORDER BY 1,2
 


/**
分組函數:avg、sum、min、count、max、group by...
**/
select e.sar+e.sex esar from emp1 e where e.sar>avg(e.sar) and e.sex>avg(e.sex) order by esar;--錯誤示範,分組函數不能用在當前位置


--group by
/**
1、group by (a,b,c)根據所有字段abc分組
2、group by rollup(a,b,c)以a為主,根據a,ab,abc分組,外加一個匯總行
3、group by cube(a,b,c)根據a,ab,ac,abc,b,bc,c分組,外加一個匯總行
**/
select job,deptno,sal,avg(sal),sum(sal) from emp1 group by job,deptno,sal;
select job,deptno,sal,avg(sal),sum(sal) from emp1 group by rollup(job,deptno,sal);
select job,deptno,sal,avg(sal),sum(sal) from emp1 group by cube(job,deptno,sal);

/**将查询结果一行显示**/
 SELECT   listagg (COLUMN, ',') WITHIN GROUP (ORDER BY COLUMN) names
       FROM TABLE

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不知道叫什麽名字

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值