Search code examples
sqlansi-sql

Implement Rank without using analytic function


I am wondering if there is a method to implement SQL analytic functions without using the inbuilt functions.

SELECT *,
    ROW_NUMBER() OVER (PARTITION BY dept_id ORDER BY salary DESC) AS rownum,
    DENSE_RANK() OVER (PARTITION BY dept_id ORDER BY salary DESC) AS denserank,
    RANK() OVER (PARTITION BY dept_id ORDER BY salary DESC) AS rnk
FROM emp;

Solution

  • Here are the three equivalent expressions:

    select emp.*,
           (select count(*)
            from emp emp2
            where emp2.dept_id = emp.dept_id and
                  (emp2.salary > emp.salary or
                   emp2.salary = emp.salary and emp2.emp_id <= emp.emp_id
                  )
           ) as "row_number",
           (select 1 + count(*)
            from emp emp2
            where emp2.dept_id = emp.dept_id and
                  emp2.salary > emp.salary 
                  )
           ) as "rank",
           (select count(distinct salary)
            from emp emp2
            where emp2.dept_id = emp.dept_id and
                  emp2.salary >= emp.salary
           ) as "dense_rank",
    from emp;
    

    This assumes the existence of an emp_id to make the rows unique for "row_number".