源码-PL/SQL从入门到精通-第九章-SQL内置函数-Part 3

这一章的SQL语句比较长,第一次接触,感觉用不习惯,可能需要在用到的时候查资料了。不管怎样,先把源码备在这里。

--排序子句(Order by)
--未指定排序时,AVG值相同
SELECT ename, sal, AVG(sal) OVER()
FROM   emp
WHERE  ROWNUM <= 3;

--指定排序后,计算累计平均值
SELECT ename, sal, AVG(sal) OVER(ORDER BY ename)
FROM   emp
WHERE  ROWNUM <= 3;

select ((select sal from emp where ename='JONES')+(select sal from emp where ename='PANDENG'))/2.0 from dual;
select sum(sal) from emp;

--开窗子句(windowing)
SELECT deptno,
       SUM(sal) 部门薪资小计,
       SUM(SUM(sal)) OVER(ORDER BY deptno ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) 部门总计
FROM   emp
GROUP  BY deptno;

--9.2.4分析函数列表
--COUNT函数
SELECT empno, ename, COUNT(*) OVER(PARTITION BY deptno  ORDER BY empno) 条数小计
FROM   emp;

--Range between
SELECT empno,
       ename,
       sal,
       COUNT(*) OVER(ORDER BY sal RANGE BETWEEN 50 PRECEDING AND 150 FOLLOWING) 薪水差异个数
FROM   emp

--AVG函数
         SELECT deptno,
                empno,
                ename,
                sal,
                AVG(sal) OVER(PARTITION BY deptno ORDER BY deptno) avg_sal
         FROM   emp;

--MIN和MAX函数
SELECT deptno,
       empno,
       ename,
       hiredate,
       sal,
       MIN(sal) OVER(PARTITION BY deptno ORDER BY hiredate RANGE UNBOUNDED PRECEDING) 最低薪水,
       MAX(sal) OVER(PARTITION BY deptno ORDER BY hiredate RANGE UNBOUNDED PRECEDING) 最高薪水
FROM   emp;

--RANK,DENSE_RANK和ROW_NUMBER函数
SELECT deptno,
       ename,
       sal,
       mgr,
       RANK() OVER(ORDER BY deptno) RANK结果,
       DENSE_RANK() OVER(ORDER BY deptno) DENSE_RANK结果,
       ROW_NUMBER() OVER(ORDER BY deptno) ROW_NUMBER结果
FROM   emp
WHERE  deptno IN (10, 20, 30) AND mgr IS NOT NULL
ORDER  BY DEPTNO;

--Min, Max函数
SELECT deptno,
       MIN(sal) KEEP(DENSE_RANK FIRST ORDER BY comm) 最低提成薪水,
       MAX(sal) KEEP(DENSE_RANK LAST ORDER BY comm) 最高提成薪水
FROM   emp
WHERE  deptno IN (10, 20, 30)
GROUP  BY deptno;

select min(sal),max(sal) from emp WHERE  deptno IN (10, 20, 30)

--FIRST和LAST函数(不太明白)
SELECT deptno,
       empno,
       sal,
       FIRST_VALUE(sal) OVER(PARTITION BY deptno  ORDER BY empno) "第一个值",
       LAST_VALUE(sal) OVER(PARTITION BY deptno  ORDER BY empno) "最后一个值"
FROM   emp
WHERE  deptno IN (10, 20);

--LAG和LEAD函数(暂且起名错位函数)
SELECT ename,
       hiredate,
       sal,
       deptno,
       LAG(sal, 1, 0) OVER(ORDER BY hiredate)  AS 前一个雇员薪水,
       LEAD(sal, 1, 0) OVER(ORDER BY hiredate) AS 后一个雇员薪水
FROM   emp
WHERE  deptno = 20;


--9.3分析函数使用示例
--记录排名
SELECT deptno,
       empno,
       ename,
       SUM(sal) dept_sales,
       RANK() OVER(PARTITION BY deptno ORDER BY SUM(sal) DESC NULLS LAST) 薪资排名_跳号,
       DENSE_RANK() OVER(PARTITION BY deptno ORDER BY SUM(sal) DESC NULLS LAST) 薪资排名_同级同号,
       ROW_NUMBER() OVER(PARTITION BY deptno ORDER BY SUM(sal) DESC NULLS LAST) 薪资排名_不跳号
FROM   emp
GROUP  BY deptno, empno, ename


DELETE
FROM   EMP
WHERE  deptno IS NULL;
SELECT *
FROM   EMP
ORDER  BY SAL
           SELECT deptno, MIN(SAL), MAX(SAL)
           FROM   EMP
           GROUP  BY deptno;

--首尾记录查询(First, last)
SELECT MIN(empno) KEEP(DENSE_RANK FIRST ORDER BY SUM(sal) DESC NULLS LAST) 薪资排名首位,
       MIN(empno) KEEP(DENSE_RANK LAST ORDER BY SUM(sal) DESC NULLS LAST) 薪资排名尾位
FROM   emp
WHERE  sal IS NOT NULL AND deptno IS NOT NULL
GROUP  BY empno;

--前后排名查询
SELECT deptno, empno, ename, dept_sales, 薪资排名
FROM   (SELECT deptno,
               empno,
               ename,
               SUM(sal) dept_sales,
               RANK() OVER(PARTITION BY deptno ORDER BY SUM(sal) DESC NULLS LAST) 薪资排名
        FROM   emp
        WHERE  deptno IS NOT NULL
        GROUP  BY deptno, empno, ename)
WHERE  薪资排名 <= 2;


SELECT deptno, empno, ename, dept_sales, 薪资排名
FROM   (SELECT deptno,
               empno,
               ename,
               SUM(sal) dept_sales,
               RANK() OVER(PARTITION BY deptno ORDER BY SUM(sal) NULLS LAST) 薪资排名
        FROM   emp
        WHERE  deptno IS NOT NULL
        GROUP  BY deptno, empno, ename)
WHERE  薪资排名 <= 2;


--层次查询(ntile)
SELECT *
FROM   (SELECT deptno,
               empno,
               ename,
               SUM(sal) dept_sales,
               NTILE(3) OVER(PARTITION BY deptno ORDER BY SUM(sal) NULLS LAST) RANK_RATIO
        FROM   emp
        WHERE  deptno IS NOT NULL
        GROUP  BY deptno, empno, ename)
WHERE  RANK_RATIO = 1 

--范围统计查询(看不大懂)
  SELECT empno,
         ename,
         hiredate,
         sal,
         MAX(sal) OVER(ORDER BY hiredate ROWS BETWEEN 10 PRECEDING AND CURRENT ROW) "前10天入职最高薪资",
         MAX(sal) OVER(ORDER BY hiredate ROWS BETWEEN CURRENT ROW AND 10 FOLLOWING) "后10天入职最高薪资"
        FROM   emp
        WHERE  deptno IN (10, 20, 30) AND sal IS NOT NULL;

--相邻记录比较
SELECT ename,
       hiredate,
       deptno,
       sal,
       sal - prev_sal "与前面的差异",
       sal - next_sal "与后面的差异"
FROM   (SELECT ename,
               hiredate,
               sal,
               deptno,
               LAG(sal, 1, 0) OVER(ORDER BY hiredate) AS prev_sal,
               LEAD(sal, 1, 0) OVER(ORDER BY hiredate) AS next_sal
        FROM   emp
        WHERE  deptno IS NOT NULL AND SAL IS NOT NULL);

--抑制重复
SELECT *
FROM   (SELECT empno,
               ename,
               sal,
               hiredate,
               ROW_NUMBER() OVER(PARTITION BY EXTRACT(YEAR FROM hiredate) ORDER BY empno) rn
        FROM   emp
        WHERE  hiredate IS NOT NULL AND
               EXTRACT(YEAR FROM hiredate) between 1980 and 2016)
WHERE  rn = 1;

--行列转换(不太明白)
SELECT deptno,
       ename,
       ROW_NUMBER() OVER(PARTITION BY deptno ORDER BY sal DESC NULLS LAST) seq
FROM   emp


         SELECT MAX(DECODE(job, '职员', ename, NULL)) "职员名称",
                MAX(DECODE(job, '职员', empno, NULL)) "职员编号",
                MAX(DECODE(job, '分析人员', ename, NULL)) "分析人员名称",
                MAX(DECODE(job, '分析人员', empno, NULL)) "分析人员编号",
                MAX(DECODE(job, '经理', ename, NULL)) "经理名称",
                MAX(DECODE(job, '经理', empno, NULL)) "经理编号",
                MAX(DECODE(job, '老板', ename, NULL)) "老板名称",
                MAX(DECODE(job, '老板', empno, NULL)) "老板编号",
                MAX(DECODE(job, '销售人员', ename, NULL)) "销售人员名称",
                MAX(DECODE(job, '销售人员', empno, NULL)) "销售人员编号"
         FROM   (SELECT job,
                        empno,
                        ename,
                        ROW_NUMBER() OVER(PARTITION BY job ORDER BY ename) rn
                 FROM   emp
                 WHERE  job IS NOT NULL) x
         GROUP  BY rn;

SELECT MAX(DECODE(job, '职员', ename, NULL)) "职员名称",
       MAX(DECODE(job, '分析人员', ename, NULL)) "分析人员名称",
       MAX(DECODE(job, '经理', ename, NULL)) "经理名称",
       MAX(DECODE(job, '老板', ename, NULL)) "老板名称",
       MAX(DECODE(job, '销售人员', ename, NULL)) "销售人员名称"
FROM   (SELECT job,
               empno,
               ename,
               ROW_NUMBER() OVER(PARTITION BY job ORDER BY ename) rn
        FROM   emp
        WHERE  job IS NOT NULL) x
GROUP  BY rn;

SELECT job, empno, ename, ROW_NUMBER() OVER(PARTITION BY job ORDER BY ename) rn
FROM   emp
WHERE  job IS NOT NULL 

--在PL/SQL中使用分析函数
DECLARE TYPE refempcur IS REF CURSOR;
empcur refempcur;
jobname VARCHAR(20); --职位名
ename VARCHAR2(20); --员工名
empno NUMBER; --员工编号
rn INT; --排名
BEGIN
  --打开游标
  OPEN empcur FOR
    SELECT job,
           empno,
           ename,
           ROW_NUMBER() OVER(PARTITION BY job ORDER BY ename) rn
    FROM   emp
    WHERE  job IS NOT NULL;
  --循环提取游标内容
  LOOP
    EXIT WHEN empcur%NOTFOUND;
    FETCH empcur
      INTO jobname, empno, ename, rn;
    --输出游标内容
    DBMS_OUTPUT.put_line(jobname || '   ' || empno || '   ' || ename || '   ' || rn);
  END LOOP;
END;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
谢谢大家的支持,我会陆续上传相关电子书 由于体积较大,本书分两卷压缩,请都下载完再解压! Oracle 11g SQL和PL SQL入门精通 pdf格式电子书 下载(一) http://download.csdn.net/source/3268267 Oracle 11g SQL和PL SQL入门精通 pdf格式电子书 下载(二) http://download.csdn.net/source/3268312 内容简介   本书是专门为oracle应用开发人员提供的sql和pl/sql编程指南。通过学习本书,读者不仅可以掌握oracle常用工具oracle universal installer、net comfiguration assistant、sql developer、sql*plus的作用及使用方法,而且可以掌握sql语句和pl/sql的各种基础知识和高级特征(记录类型、集合类型、对象类型、大对象类型)。   除了为读者提供编写sql语句和开发pl/sql块的方法外,本书还为应用开发人员提供了一些常用的pl/sql系统包。通过使用这些pl/sql系统包,应用开发人员可以开发出功能更强大的数据库应用程序。本书不仅适合sql和pl/sql初学者,也适合于有经验的oracle应用开发人员。 前言 第一部分 sql和pl/sql相关工具  第1章 在windows 平台上安装oracle database 11g  第2章 配网络服务名  第3章 使用sql database  第4章 使用sql*plus 第二部分 sql  第5章 sql和pl/sql综述  第6章 简单查询  第7章 sql单行函数  第8章 操纵数据  第9章 复杂查询  第10章 管理常用对象 第三部分 pl/sql  第11章 pl/sql基础  第12章 访问oracle  第13章 编写控制结构  第14章 使用复合数据类型  第15章 使用游标  第16章 异常处理 . 第17章 本地动态sql  第18章 pl/sql过程  第19章 pl/sql函数  第20章 pl/sql包  第21章 触发器  第22章 使用对象类型 第四部分 pl/sql系统包  第23章 使用大对象  第24章 读写os文件  第25章 开发多媒体应用  第26章 开发web应用  第27章 dbms_sq动态sql  第28章 管理统计  第29章 使用数据库资管理器  第30章 数据加密和解密  第31章 使用调度程序  第32章 使用flashback  第33章 使用重定义联机表  第34章 修正损坏块  第35章 使用日里民挖掘  第36章 使用管道  第37章 使用精细访问控制  第38章 使用精细审计  第39章 使用预警事件  第40章 转换rowid  第41章 其他常用包 习题答案
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值