--创建测试表
CREATE TABLE ORDER_TEST(ID NUMBER,EMPID NUMBER,SAL NUMBER(10,2));
--依然使用序列
CREATE SEQUENCE SEQ_ORDER_TEST
MINVALUE 1
MAXVALUE 99999
START WITH 1
INCREMENT BY 1;
--插入数据
INSERT INTO ORDER_TEST(ID,EMPID,SAL) VALUES(SEQ_ORDER_TEST.NEXTVAL,&EMPID,&SAL);
--查看一下数据【COMMIT;】
SELECT * FROM ORDER_TEST;
--ROW_NUMBER() OVER[排名:1,2,3,4,5,6,7,8……]
SELECT ID,EMPID,SAL,ROW_NUMBER() OVER(PARTITION BY EMPID ORDER BY SAL) OR_1,ROW_NUMBER() OVER(ORDER BY SAL) OR_2 FROM ORDER_TEST ORDER BY EMPID,4;
--RANK() OVER[排名:1,2,2,2,2,6,7,7,9……]
SELECT ID,EMPID,SAL,RANK() OVER(PARTITION BY EMPID ORDER BY SAL) OR_1,RANK() OVER(ORDER BY SAL) OR_2 FROM ORDER_TEST ORDER BY EMPID,4;
--DENSE_RANK() OVER[排名:1,2,2,2,2,3,4,4,5……]
SELECT ID,EMPID,SAL,DENSE_RANK() OVER(PARTITION BY EMPID ORDER BY SAL) OR_1,DENSE_RANK() OVER(ORDER BY SAL) OR_2 FROM ORDER_TEST ORDER BY EMPID,4;
--RATIO_TO_REPORT() OVER[用于对汇总的统计信息计算比率,即分项占汇总数的比列]
SELECT ID,EMPID,SAL,RATIO_TO_REPORT(SAL) OVER()RR FROM ORDER_TEST;
--RATIO_TO_REPORT() OVER [占分组内总数的比例]
SELECT ID,EMPID,SAL,RATIO_TO_REPORT(SAL) OVER(PARTITION BY EMPID ) RR FROM ORDER_TEST;
--工资前三名
WITH A AS
(SELECT ID,EMPID,SAL,ROW_NUMBER() OVER(PARTITION BY EMPID ORDER BY SAL) OR_1,ROW_NUMBER() OVER(ORDER BY SAL DESC) OR_2 FROM ORDER_TEST)
SELECT * FROM A WHERE A.OR_2<=3;
--FIRST,LAST(将空值排名置第一,置倒数第一)有时候排名 空值往往会排到第一位。这样结果不是我们想要的。所以ORACEL给出了NULLS LAST/NULLS FIRT解决办法
SELECT ID,EMPID,SUM(SAL),ROW_NUMBER() OVER(PARTITION BY EMPID ORDER BY SUM(SAL) DESC /*NULLS FIRST*/) OR_1 FROM ORDER_TEST GROUP BY ID,EMPID;
SELECT ID,EMPID,SUM(SAL),ROW_NUMBER() OVER(PARTITION BY EMPID ORDER BY SUM(SAL) DESC NULLS LAST) OR_1 FROM ORDER_TEST GROUP BY ID,EMPID;
--@@@@注:语句格式基本上是这样.书本格式不会。大部分我都是这么在用。MIN()/MAX() KEEP (DENSE_RANK FIRST/LAST ORDER BY [ASC/DESC]) [OVER([PARTIITON BY ])]
--查看序号[就相当于我们单位的工号]最小[大]工资最多[最少]的。BOSS想看看哪个新入职员工工资涨的最快,哪个最慢
SELECT MIN(ID) KEEP(DENSE_RANK FIRST ORDER BY SAL DESC NULLS LAST) FIRST,
MAX(ID) KEEP(DENSE_RANK FIRST ORDER BY SAL DESC NULLS LAST) MAX_FIRST,
MIN(ID) KEEP(DENSE_RANK LAST ORDER BY SAL DESC) LAST,
MAX(ID) KEEP(DENSE_RANK LAST ORDER BY SAL DESC) MAX_LAST
FROM ORDER_TEST;
--带上OVER(),对每一条记录计算。
SELECT ID,EMPID,SAL,
MIN(ID) KEEP(DENSE_RANK FIRST ORDER BY SAL DESC NULLS LAST) OVER() FIRST,
MAX(ID) KEEP(DENSE_RANK FIRST ORDER BY SAL DESC NULLS LAST) OVER() MAX_FIRST,
MIN(ID) KEEP(DENSE_RANK LAST ORDER BY SAL DESC) OVER() LAST,
MAX(ID) KEEP(DENSE_RANK LAST ORDER BY SAL DESC) OVER() MAX_LAST
FROM ORDER_TEST;
--求每个部门序号[就相当于我们单位的工号]最小[大]工资最多[最少]的。
SELECT ID,EMPID,SAL,
MIN(ID) KEEP(DENSE_RANK FIRST ORDER BY SAL DESC NULLS LAST) OVER(PARTITION BY EMPID) FIRST,
MAX(ID) KEEP(DENSE_RANK FIRST ORDER BY SAL DESC NULLS LAST) OVER(PARTITION BY EMPID) MAX_FIRST,
MIN(ID) KEEP(DENSE_RANK LAST ORDER BY SAL DESC) OVER(PARTITION BY EMPID) LAST,
MAX(ID) KEEP(DENSE_RANK LAST ORDER BY SAL DESC) OVER(PARTITION BY EMPID) MAX_LAST
FROM ORDER_TEST;
--NTIL函数为各个记录在记录集中的排名计算比例[4就是4个分档,5就是5个分档]
SELECT ID,EMPID,SUM(SAL),NTILE(4)OVER(ORDER BY SUM(SAL) DESC NULLS LAST) OR_1 FROM ORDER_TEST GROUP BY ID,EMPID;
--查询收入是前25%的用户
WITH A AS
(SELECT ID,EMPID,SUM(SAL),NTILE(4)OVER(ORDER BY SUM(SAL) DESC NULLS LAST) OR_1 FROM ORDER_TEST GROUP BY ID,EMPID)
SELECT * FROM A WHERE OR_1=1;