Top 10 Analytic Functions in Oracle

SQL analytic functions in Oracle, with input and output examples

Analytic functions (also called window functions) operate over a set of rows and return values for each row, unlike aggregate functions which collapse rows into one.

Top 10 Analytic Functions in Oracle

FunctionPurposeExample InputExample QueryExample Output
ROW_NUMBER()Assigns unique sequential number to rowsEmployees table with salariesSELECT emp_name, salary, ROW_NUMBER() OVER (ORDER BY salary DESC) AS rn FROM employees;Each employee gets a unique rank (1,2,3…)
RANK()Assigns rank with gaps for tiesEmployees with same salarySELECT emp_name, salary, RANK() OVER (ORDER BY salary DESC) AS rnk FROM employees;If two employees tie at rank 1, next rank is 3
DENSE_RANK()Assigns rank without gapsSame as aboveSELECT emp_name, salary, DENSE_RANK() OVER (ORDER BY salary DESC) AS drnk FROM employees;If two tie at rank 1, next rank is 2
NTILE(n)Distributes rows into n bucketsEmployees salariesSELECT emp_name, salary, NTILE(4) OVER (ORDER BY salary DESC) AS quartile FROM employees;Divides salaries into 4 quartiles
LEAD()Accesses next row’s valueEmployees salariesSELECT emp_name, salary, LEAD(salary) OVER (ORDER BY salary) AS next_sal FROM employees;Shows next higher salary
LAG()Accesses previous row’s valueEmployees salariesSELECT emp_name, salary, LAG(salary) OVER (ORDER BY salary) AS prev_sal FROM employees;Shows previous lower salary
FIRST_VALUE()Returns first value in windowEmployees salariesSELECT emp_name, salary, FIRST_VALUE(salary) OVER (ORDER BY salary DESC) AS top_sal FROM employees;Shows highest salary for all rows
LAST_VALUE()Returns last value in windowEmployees salariesSELECT emp_name, salary, LAST_VALUE(salary) OVER (ORDER BY salary DESC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS bottom_sal FROM employees;Shows lowest salary for all rows
CUME_DIST()Cumulative distribution (fraction ≤ current row)Employees salariesSELECT emp_name, salary, CUME_DIST() OVER (ORDER BY salary) AS cd FROM employees;Values between 0 and 1 showing percentile
PERCENT_RANK()Relative rank as percentageEmployees salariesSELECT emp_name, salary, PERCENT_RANK() OVER (ORDER BY salary) AS pr FROM employees;Shows relative position (0–1)

Example Walkthrough (Employees Table)

Suppose we have:

CREATE TABLE employees (
  emp_id NUMBER,
  emp_name VARCHAR2(50),
  salary NUMBER
);

INSERT INTO employees VALUES (1, 'Alice', 5000);
INSERT INTO employees VALUES (2, 'Bob', 7000);
INSERT INTO employees VALUES (3, 'Charlie', 7000);
INSERT INTO employees VALUES (4, 'David', 9000);
INSERT INTO employees VALUES (5, 'Eve', 4000);

Employees Table (Input Data)

emp_idemp_namesalary
1Alice5000
2Bob7000
3Charlie7000
4David9000
5Eve4000

Analytic Functions with Query + Output

1. ROW_NUMBER()

SELECT emp_name, salary,
       ROW_NUMBER() OVER (ORDER BY salary DESC) AS row_num
FROM employees;
emp_namesalaryrow_num
David90001
Bob70002
Charlie70003
Alice50004
Eve40005

2. RANK()

SELECT emp_name, salary,
       RANK() OVER (ORDER BY salary DESC) AS rnk
FROM employees;
emp_namesalaryrnk
David90001
Bob70002
Charlie70002
Alice50004
Eve40005

3. DENSE_RANK()

SELECT emp_name, salary,
       DENSE_RANK() OVER (ORDER BY salary DESC) AS drnk
FROM employees;
emp_namesalarydrnk
David90001
Bob70002
Charlie70002
Alice50003
Eve40004

4. NTILE(3)

SELECT emp_name, salary,
       NTILE(3) OVER (ORDER BY salary DESC) AS bucket
FROM employees;
emp_namesalarybucket
David90001
Bob70001
Charlie70002
Alice50002
Eve40003

5. LEAD()

SELECT emp_name, salary,
       LEAD(salary) OVER (ORDER BY salary DESC) AS next_sal
FROM employees;
emp_namesalarynext_sal
David90007000
Bob70007000
Charlie70005000
Alice50004000
Eve4000NULL

6. LAG()

SELECT emp_name, salary,
       LAG(salary) OVER (ORDER BY salary DESC) AS prev_sal
FROM employees;
emp_namesalaryprev_sal
David9000NULL
Bob70009000
Charlie70007000
Alice50007000
Eve40005000

7. FIRST_VALUE()

SELECT emp_name, salary,
       FIRST_VALUE(salary) OVER (ORDER BY salary DESC) AS top_sal
FROM employees;
emp_namesalarytop_sal
David90009000
Bob70009000
Charlie70009000
Alice50009000
Eve40009000

8. LAST_VALUE()

SELECT emp_name, salary,
       LAST_VALUE(salary) OVER (ORDER BY salary DESC
       ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS bottom_sal
FROM employees;
emp_namesalarybottom_sal
David90004000
Bob70004000
Charlie70004000
Alice50004000
Eve40004000

9. CUME_DIST()

SELECT emp_name, salary,
       CUME_DIST() OVER (ORDER BY salary) AS cd
FROM employees;
emp_namesalarycd
Eve40000.2
Alice50000.4
Bob70000.8
Charlie70000.8
David90001.0

10. PERCENT_RANK()

SELECT emp_name, salary,
       PERCENT_RANK() OVER (ORDER BY salary) AS pr
FROM employees;
emp_namesalarypr
Eve40000.0
Alice50000.25
Bob70000.75
Charlie70000.75
David90001.0

Leave a Reply