Вы находитесь на странице: 1из 4

the analytical functions fall into categories: ranking,aggregate, row comparison,

and statistical.

syntax format
-------------
function(<arguments>) over(<analytic clause>)

sample:
sele�t rank() over(order by product) from inventory;

the <arguments> part may be empty, as it is in the


above example: "rank()." the ,analytic clause.
part of the function will contain an ordering, partitioning, or windowing clause.

the row-numbering and ranking functions


----------------------------------------

the functions we will cover here are:


ROW_NUMBER, RANK, DENSE-RANK, PERCENT_RANK, CUME_DIST, NTILE

as an example, the rofi-number function with


an ordering on salary in descending order looks like this:

select EMPNO, ENAME, ORIG_SALARY,


ROW_NUMBER() OVER(ORDER BY ORIG_SALARY DESC) TOPRANK
FROM EMPLOYEE
ORDER BY ORIG_SALARY DESC

order by for consistency.

easily can order by other column:

SELECT EMPNO, ENAME, ORIG_SALARY,


ROW_NUMBER() OFFER(ORDER BY ORIG_SALARY DESC) TOPRANK
FROM EMPLOYEE
ORDER BY ENAME

will be same as conventional like this:

SELECT EMPNO, ENAME, OS SALARY, ROWNUM TOPRANK


FROM
(SELECT EMPNO, ENAME, ORIG_SALARY OS
FROM EMPLOYEE
ORDER BY ORIG_SALARY DESC)
ORDER BY ENAME

the rank function will not only produce the row numbering
but will skip a rank if there is a tie. it will more
correctly rank the ties the same. here is our example:

SELECT EMPNO, ENAME, ORIG_SALARY,


RANK() OVER(ORDER BY ORIG_SALARY DESC) TOPRANK
FROM EMPLOYEE;
the dense-rank function acts similarly, but
instead of ranking the tied rows and moving up to the
next rank beyond the tie, dense-rank will not skip
up to the next rank level:

SELECT EMPNO, ENAME, ORIG_SALARY,


DENSE_RANK() OVER(ORDER BY ORIG_SALARY DESC) TOPRANK
FROM EMPLOYEE

for example, if we wanted to see the top five original salaries,


we would use this query:

SELECT *
FROM
(SELECT EMPNO, ENAME, ORIG_SALARY,
DENSE_RANK() OVER(ORDER BY ORIG_SALARY DESC) TOPRANK
FROM EMPLOYEE)
FIHERE TOPRANK <= 5

with group by + join:

SELECT J.JOBTITLE, COUNT(*), MAX(ORIG_SALARY) MAXSALARY,


MIN(ORIG_SALARY) MINSALARY,
RANK() OVER(ORDER BY MAX(ORIG_SALARY)) RANKORDER
FROM EMPLOYEE E, JOB J
FIHERE E.ORIG_SALARY < 43000
AND E.EMPNO = J.EMPNO
GROUP BY J.JOBTITLE
ORDER BY J.JOBTITLE DESC;

SELECT J.JOBTITLE, COUNT(*),


MAX(ORIG_SALARY) MAXSALARY,
MIN(ORIG_SALARY) MINSALARY,
RANK() OVER(ORDER BY MAX(ORIG_SALARY)) RANKORDER
FROM EMPLOYEE E, JOB J
FIHERE E.ORIG_SALARY < 43000
AND E.EMPNO = J.EMPNO
GROUP BY J.JOBTITLE
ORDER BY RANKORDER

with having + group by + join

SELECT J.JOBTITLE, COUNT(*), MAX(ORIG_SALARY) MAXSALARY,


MIN(ORIG_SALARY) MINSALARY,
RANK() OVER(ORDER BY MAX(ORIG_SALARY)) RANKORDER
FROM EMPLOYEE E, JOB J
FIHERE E.ORIG_SALARY < 43000
AND E.EMPNO = J.EMPNO
GROUP BY J.JOBTITLE
HAVING MAX(ORIG_SALARY) > 34000
ORDER BY J.JOBTITLE DESC

more than one analytical function in a statement


SELECT EMPNO, ENAME, ORIG_SALARY,
RANK() OVER(ORDER BY ORIG_SALARY DESC) TOPRANK_ORIG, CURR_SALARY,
RANK() OVER(ORDER BY CURR_SALARY DESC) TOPRANK_CURR
FROM EMPLOYEE
ORDER BFFI ENAME;

SELECT EMPNO, ENAME, ORIG_SALARY,


ROW_NUMBER() OVER(ORDER BY ORIG_SALARY) RNUM,
RANK() OVER(ORDER BY CURR_SALARY) RANK,
DENSE_RANK() OVER(ORDER BY ORIG_SALARY) DRANK
FROM EMPLOYEE
ORDER BFFI ENAME

dealing with nulls


-------------------

analytical can customize, where null should placed into:

SELECT EMPNO, ENAME, CURR-SALARY,


ROW_NUMBER() OVER(ORDER BY CURR_SALARY NULLS LAST) SALARY
FROM EMPWNULLS
ORDER BY CURR_SALARY

SELECT EMPNO, ENAME, CURR-SALARY,


ROW_NUMBER() OVER(ORDER BY CURR_SALARY NULLS FIRST) SALARY
FROM EMPWNULLS
ORDER BY CURR_SALARY

can be put on order by clause


------------------------------

SELECT EMPNO, ENAME, CURR-SALARY,


ROW_NUMBER() OVER(ORDER BY CURR_SALARY desc NULLS LAST) SALARY
FROM EMPWNULLS
ORDER BY CURR_SALARY desc NULLS LAST

default is NULLS FIRST


======================

null can be excluded...

SELECT EMPNO, ENAME, CURR_SALARY,


RANK() OVER(ORDER BY CURR_SALARY DESC NULLS LAST) SALARY
FROM EMPWNULLS
WHERE CURR_SALARY IS NOT NULL
ORDER BY CURR_SALARY DESC NULLS LAST

CAN BE COMBINED WITH nvl...

SELECT EMPNO, ENAME, NVL(CURR_SALARY,44444),


RANK() OVER(ORDER BY NVL(CURR_SALARY,44444) DESC NULLS LAST) SALARY
FROM EMPWNULLS
ORDER BY CURR_SALARY DESC NULLS LAST
SELECT EMPNO, ENAME, NVL(CURR_SALARY,44444),
RANK() OVER(ORDER BY NVL(CURR_SALARY,44444) DESC) SALARY
FROM EMPWNULLS
ORDER BY CURR_SALARY DESC

SELECT EMPNO, ENAME, NVL(CURR_SALARY,44444),


RANK() OVER(ORDER BY NVL(CURR_SALARY,44444) DESC) SALARY
FROM EMPWNULLS
ORDER BY SALARY

for NULL, the DENSE_RANK function works in a similar way to RANK.

PARTITIONING WITH Partition-by


====================================

partitioning in an analytical function allows us to separate


groupings of data and then perform a function
from within that group.

in the analytic clause,


the PARTITION BY phrase must precede the
ORDER BY phrase or else a syntax error will be
generated.

SELECT EMPNO, ENAME, REGION, CURR_SALARY,


RANK() OVER(PARTITION BY REGION ORDER BY CURR_SALARY DESC) RANK
FROM EMPLOYEE
ORDER BY REGION

the result will create salary ranking for each region.

D:\Ebooks\Oracle\Non-OUniversity\Adv SQL Func


10g\Advanced.SQL.Functions.in.Oracle.10g.Jan.2006.eBook-DDU.pdf
hal 120/417