ORACLEC学习笔记(7)(排名函数、行列转换)

分析函数:排名函数
RANK(), DENSE_RANK()与 ROW_NUMBER():

RANK,DENSE_RANK,ROW_NUMBER函数为每条记录产生一个从1开始至N的自然数,
N的值可能小于等于记录的总数。这3个函数的唯一区别在于当碰到相同数据时的排名策略。
①ROW_NUMBER:
ROW_NUMBER函数返回一个唯一的值,当碰到相同数据时,排名按照记录集中记录的顺序依次递增。
②DENSE_RANK:
DENSE_RANK函数返回一个唯一的值,当碰到相同数据时,此时所有相同数据的排名都是一样的。
③RANK:
RANK函数返回一个唯一的值,当碰到相同的数据时,此时所有相同数据的排名是一样的,
同时会在最后一条相同记录和下一条不同记录的排名之间空出排名。

-----查询EMP表所有员工姓名,工资以部门分组降序排序

SELECT
      A1.ENAME
     ,A1.SAL 
    --- ,A1.DEPTNO
FROM (SELECT
           A.ENAME
          ,A.SAL
          ,A.DEPTNO
          ,ROW_NUMBER()OVER(PARTITION BY A.DEPTNO ORDER BY A.SAL  DESC) ROW_N
      FROM EMP A
      )A1
WHERE A1.ROW_N<15

-------------查询EMP表中工资排名在第5到第10名的员工姓名、工作岗

位、工资
SELECT
      A1.ENAME
     ,A1.JOB
     ,A1.SAL 
FROM (SELECT
             A.ENAME
            ,A.JOB 
            ,A.SAL
            ,ROW_NUMBER()OVER(ORDER BY A.SAL DESC) ROW_M
        FROM EMP A
        )A1
WHERE A1.ROW_M BETWEEN 5 AND 10;        

  1. LAG()与 LEAD():求之前或之后的第N行

LAG 和 LEAD 函数可以在一次查询中取出同一字段的前N行的数据和后N行的值。
这种操作可以使用对相同表的表连接来实现,不过使用 LAG 和 LEAD 有更高的效率。

LAG(ARG1,ARG2,ARG3)
第一个参数是列名,
第二个参数是偏移的offset,
第三个参数是超出记录窗口时的默认值。----一般不用写

—比较EMP表中员工与上一个入职员工晚入职多久

SELECT
    /* A1.姓名
    ,A1.较晚入职的时间
    ,A1.较早入职的时间
    ,*/A1.较晚入职的时间- A1.较早入职的时间 相差入职的时间
FROM ( SELECT
           A.ENAME     姓名
          ,A.HIREDATE   较晚入职的时间
          ,LAG(A.HIREDATE,1)OVER(ORDER BY A.HIREDATE ) 较早入职的时间
      FROM EMP A
      )A1
WHERE A1.较早入职的时间 IS NOT  NULL;

SELECT
    /* A1.姓名
    ,A1.较晚入职的时间
    ,A1.较早入职的时间
    ,*/A1.较晚入职的时间- A1.较早入职的时间 相差入职的时间
FROM (
      SELECT
           A.ENAME     姓名
          ,A.HIREDATE   较早入职的时间
          ,LEAD(A.HIREDATE,1)OVER(ORDER BY A.HIREDATE )  较晚入职的时间
      FROM EMP A
      )A1
WHERE A1.较晚入职的时间 IS NOT  NULL;

------查询EMP表中每个部门的员工工资相差多少钱

SELECT 
      A.EMPNO,
     A.ENAME, 
    ABS(A.SAL-B.SAL)
FROM EMP A
INNER JOIN EMP B
        ON  A.DEPTNO=B.DEPTNO 
       AND A.EMPNO<B.EMPNO 

-------------查询EMP表中每个部门的员工工资从高到底依次相差多少钱

SELECT
      A1.DEPTNO
      ,A1.SAL-A1.LEAD_SAL
FROM(SELECT
           A.EMPNO,
           A.ENAME,
           A.JOB,
           A.MGR,
           A.HIREDATE,
           A.SAL,
           LEAD(A.SAL,1)OVER(PARTITION BY A.DEPTNO ORDER BY A.SAL DESC) LEAD_SAL,
           A.COMM,
           A.DEPTNO
      FROM EMP A 
      )A1
WHERE A1.LEAD_SAL IS NOT NULL;      
------------------------------------------------      

----4.3 行列转换 (LAG LEAD )
在用户制作数据报表时,经常会使用到表数据的行列转换操作。

1.列转行:

【例】有一张表S,记录了某公司每个月的销售额,如下
Y Q AMT
2015 1 100
2015 2 110
2015 3 130
2015 4 100
2016 1 200
2016 2 150
2016 3 100
2016 4 300

Y Q1 Q2 Q3 Q4
2015 100 110 130 100
2016 200 150 100 300

CREATE TABLE S
              (
                Y  NUMBER    
               ,Q  NUMBER   
               ,AMT NUMBER
        );

INSERT INTO S VALUES (2015,1,100);
INSERT INTO S VALUES (2015,2,110);
INSERT INTO S VALUES (2015,3,130);
INSERT INTO S VALUES (2015,4,100);
INSERT INTO S VALUES (2016,1,200);
INSERT INTO S VALUES (2016,2,150);
INSERT INTO S VALUES (2016,3,100);
INSERT INTO S VALUES (2016,4,300);
COMMIT;  
SELECT * from s;   

—(1)用分析函数lead/lag
-------LAG的方法

SELECT
      A1.Y
     ,A1.Q1
     ,A1.Q2
     ,A1.Q3
     ,A1.Q4 
FROM (SELECT
            A.Y
           ,A.Q
           ,A.AMT Q4 
           ,LAG(A.AMT,1)OVER(PARTITION BY A.Y ORDER BY 1 ) Q3
           ,LAG(A.AMT,2)OVER(PARTITION BY A.Y ORDER BY 1 ) Q2
           ,LAG(A.AMT,3)OVER(PARTITION BY A.Y ORDER BY 1 ) Q1
      FROM S A
      )A1
WHERE A1.Q=4;

-----------LEAD 的方法

SELECT
     A1.Y
    ,A1.Q1
    ,A1.Q2
    ,A1.Q3
    ,A1.Q4 
FROM (SELECT
           A.Y
          ,A.Q
          ,A.AMT  Q1
          ,LEAD(A.AMT,1)OVER(PARTITION BY A.Y ORDER BY 1 ) Q2
          ,LEAD(A.AMT,2)OVER(PARTITION BY A.Y ORDER BY 1 ) Q3
          ,LEAD(A.AMT,3)OVER(PARTITION BY A.Y ORDER BY 1 ) Q4
      FROM S A 
      )A1
WHERE A1.Q=1;

----方法3:CASE WHEN 的方法

SELECT
       A.Y
      ,SUM(CASE WHEN A.Q=1 THEN A.AMT ELSE 0 END ) Q1
      ,SUM(CASE WHEN A.Q=2 THEN A.AMT ELSE 0 END ) Q2
      ,SUM(CASE WHEN A.Q=3 THEN A.AMT ELSE 0 END ) Q3
      ,SUM(CASE WHEN A.Q=4 THEN A.AMT ELSE 0 END ) Q4
FROM S A 
GROUP BY A.Y;
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值