SELECT DECODE(ORG.ORG_NAME,'','合计',ORG.ORG_NAME) 地市局,B.CREATE_COUNT 总数 FROM (SELECT A.ORGANIZATION_ID,COUNT(1) CREATE_COUNT FROM (SELECT F.CREATE_TIME,(SELECT max(ORG.ORG_ID) keep(dense_rank first order by DECODE(ORG.ORG_TYPE,4,1)) FROM TOP_ORGANIZATION ORG START WITH ORG.ORG_ID = FR.ORGANIZATION_ID CONNECT BY ORG.ORG_ID = PRIOR ORG.PARENT_ORG_ID) ORGANIZATION_ID,F.TASK_STATUS_DESCRIBE FROM SP_PD_FAULT_REPORT FR,SP_PD_FAULT F WHERE F.CREATE_TIME BETWEEN TO_DATE('2017-04-01 00:00:00','YYYY-MM-DD HH24:MI:SS') AND TO_DATE('2017-05-31 00:00:00','YYYY-MM-DD HH24:MI:SS') AND F.ID = FR.FAULT_ID) A GROUP BY ROLLUP(A.ORGANIZATION_ID)) B,TOP_ORGANIZATION ORG WHERE B.ORGANIZATION_ID = ORG.ORG_ID(+) AND lnnvl(ORG.ORG_TYPE != 4) ORDER BY ORG.SORT_NO ASC;
- --emp表的数据
- sql>SELECTt.empno,
- 2t.ename,250)"> 3t.mgr,250)"> 4t.sal,250)"> 5t.deptno
- 6FROMempt
- 7ORDERBYt.sal,250)"> 8t.deptno;
- EMPNOENAMEMGRSALDEPTNO
- ------------------------------------------------------------
- 111aaa22228009
- 7369SMITH790280020
- 7900JAMES769895030
- 7876ADAMS7788110020
- 7521WARD7698125030
- 7654MARTIN7698125030
- 7934MILLER7782130010
- 7844TURNER7698150030
- 7499ALLEN7698160030
- 7782CLARK7839245010
- 7698BLAKE7839285030
- 7566JONES7839297520
- 7788SCOTT7566300020
- 7902FORD7566300020
- 7839KING500010
- 222bbb3333500040
- --1.现在要查询表中工资最高的部门号的最大最小值,工资最低的部门号的最大最小值
- --因为是DENSE_RANK,会产生重复数据,使用min,max取一条。
- --这个sql没有使用over子句,后面的例子会使用
- SELECTMIN(t.deptno)KEEP(DENSE_RANKFIRSTBYt.sal)a,250)"> 2MAX(t.deptno)KEEP(DENSE_RANKBYt.sal)b,250)"> 3LASTBYt.sal)c,250)"> 4BYt.sal)d
- 5FROMempt;
- ABCD
- ----------------------------------------
- 9201040
- --2.加上over,对每一行记录做计算,看看效果:
- sql>
- 5t.deptno,85); font-weight:bold">BYt.sal)OVER()a,85); font-weight:bold">BYt.sal)OVER()b,250)"> 8BYt.sal)OVER()c,250)"> 9BYt.sal)OVER()d
- 10 11 12t.deptno
- 13;
- EMPNOENAMEMGRSALDEPTNOABCD
- ---------------------------------------------------------------------------
- 111aaa2222800.0099201040
- 7369SMITH7902800.00209201040
- 7900JAMES7698950.00309201040
- 7876ADAMS77881100.00209201040
- 7521WARD76981250.00309201040
- 7654MARTIN76981250.00309201040
- 7934MILLER77821300.00109201040
- 7844TURNER76981500.00309201040
- 7499ALLEN76981600.00309201040
- 7782CLARK78392450.00109201040
- 7698BLAKE78392850.00309201040
- 7566JONES78392975.00209201040
- 7788SCOTT75663000.00209201040
- 7902FORD75663000.00209201040
- 7839KING5000.00109201040
- 222bbb33335000.00409201040
- --3.下面对每一个mgr求最大(最小)工资的部门号的最大(最小)值
- BYt.sal)OVER(PARTITIONBYt.mgr)a,85); font-weight:bold">BYt.mgr)b,85); font-weight:bold">BYt.mgr)c,85); font-weight:bold">BYt.mgr)d
- 111aaa2222800.0099999
- 7369SMITH7902800.002020202020
- 7900JAMES7698950.003030303030
- 7876ADAMS77881100.002020202020
- 7654MARTIN76981250.003030303030
- 7521WARD76981250.003030303030
- 7934MILLER77821300.001010101010
- 7844TURNER76981500.003030303030
- 7499ALLEN76981600.003030303030
- 7782CLARK78392450.001010102020
- 7698BLAKE78392850.003010102020
- 7566JONES78392975.002010102020
- 7902FORD75663000.002020202020
- 7788SCOTT75663000.002020202020
- 7839KING5000.001010101010
- 222bbb33335000.004040404040
最近在工作中,碰到一个问题,后来在处理过程中接触到了KEEP,DENSE_RANK分析函数,问题瞬间被简单的解决,否则按照常规写法,肯定会写出嵌套语句,但是网上对这个方面的介绍比较少,现在特整理了一下:
从目前查到的来看:DENSE_RANK是和KEEP结合使用的,网上给出的解释是Returns the row rankedfirstusing DENSE_RANK。我的理解是返回DENSE_RANK函数的第一结果。一般写法是MIN [ MAX ] (A) KEEP(DENSE_RANK FIRST [ LAST ] ORDER BY B),这里引用别人说的明的解释一下:
DENSE_RANK
功能描述:根据ORDER BY子句中表达式的值,从查询返回的每一行,计算它们与其它行的相对位置。组内的数据按ORDER BY子句排序,然后给每一行赋一个号,从而形成一个序列,该序列从1开始,往后累加。每次ORDER BY表达式的值发生变化时,该序列也随之增加。有同样值的行得到同样的数字序号(认为null时相等的)。密集的序列返回的时没有间隔的数。
FIRST
功能描述:从DENSE_RANK返回的集合中取出排在最前面的一个值的行(可能多行,因为值可能相等),因此完整的语法需要在开始处加上一个集合函数以从中取出记录。
LAST
所以默认排序下,FIRST可以理解是取小值,LAST取大值。而前面的MIN或者MAX则是在KEEP的结果集中取某一字段的最大值或最小值。
语文没学好
上面的可能没说清楚,而且网上的相关的资料也少,所以最后给大家看一个完整的sql语句并解释一下作用,大家自己理解一下吧....
- SELECTZGH,
- MIN(WM)KEEP(DENSE_RANKFIRSTORDERBYWM),
- MIN(RQ)KEEP(DENSE_RANKBYWM)
- FROMT_JZG
- GROUPBYZGH
表结构大概如下:
ZGH | WM | RQ |
A | 1 | 20130101 |
A | 2 | 20140102 |
A | 1 | 20120102 |
B | 3 | 20131001 |
B | 2 | 20140102 |
B | 3 | 20121004 |
其中相同ZGH对应的字段WM、RQ值可能有多条,要求从中取出WM值最小的那一条,但可能存在多条,这时要取出其中RQ最小的那一条,以上语句可以实现。
最后取出的值应该是:
ZGH | WM | RQ |
A | 1 | 20120102 |
B | 2 | 20140102 |