Reputation: 13
So I am really happy being able to rank results based on effective dates, but currently I'm having an issue where one data element repeats (POD) while another changes based on EFFDT (DEPT).
I only want to rank unique values for Pod, and later Dept. However Pod is based on Dept, which changes more frequently. The below code gives me:
EENBR PodRank POD DeptRank DeptNbr DeptEffdt
100 1 73 1 12420 4/11/2005
100 2 73 2 12560 5/22/2005
100 3 73 3 12501 6/24/2007
200 1 12 1 50768 3/14/2005
200 2 13 2 10949 9/9/2012
300 1 73 1 12450 3/21/2005
300 2 73 2 12471 12/25/2005
300 3 73 3 12581 12/21/2008
300 4 73 4 12585 6/6/2010
300 5 73 5 12432 5/19/2013
SELECT DISTINCT
AL4.FULL_NAME,
AL4.EMPLOYEE_NUMBER,
dense_rank() over (partition by AL4.EMPLOYEE_NUMBER
order by AL3.EFFECTIVE_START_DATE) as POD_RANKING,
AL7.POD_NBR as POD,
row_number() over (partition by AL4.EMPLOYEE_NUMBER
order by AL3.EFFECTIVE_START_DATE) as DEPT_RANKING,
AL3.RECORDVALUE AS DEPT_NUMBER,
AL3.EFFECTIVE_START_DATE AS "DEPT EFFECTIVE DATE"
FROM T1 AL3,
T2 AL4,
T3 AL7
WHERE AL4.PERSON_ID = AL3.PERSON_ID
AND AL4.EMPLOYEE_NUMBER = AL3.EMPLOYEE_NUMBER
AND AL3.RECORDTYPE = 'DEPARTMENT_NUMBER'
AND AL7.DEPT_NBR = AL3.RECORDVALUE
Order By AL4.Employee_Number;
Is there a function that only ranks unique values?
Upvotes: 1
Views: 5957
Reputation: 60462
There's no function for this, but you can get the result when you use nested window functions:
SELECT dt.*,
SUM(flag) OVER (PARTITION BY EMPLOYEE_NUMBER
ORDER BY "DEPT EFFECTIVE DATE") AS POD_RANKING
FROM
(
SELECT
AL4.FULL_NAME,
AL4.EMPLOYEE_NUMBER,
AL7.POD_NBR AS POD,
ROW_NUMBER() OVER (PARTITION BY AL4.EMPLOYEE_NUMBER
ORDER BY AL3.EFFECTIVE_START_DATE) AS DEPT_RANKING,
AL3.RECORDVALUE AS DEPT_NUMBER,
AL3.EFFECTIVE_START_DATE AS "DEPT EFFECTIVE DATE",
CASE WHEN ROW_NUMBER()
OVER (PARTITION BY AL4.EMPLOYEE_NUMBER,AL7.POD_NBR
ORDER BY AL3.EFFECTIVE_START_DATE) = 1 THEN 1 ELSE 0 END AS flag
FROM T1 AL3,
T2 AL4,
T3 AL7
WHERE AL4.PERSON_ID = AL3.PERSON_ID
AND AL4.EMPLOYEE_NUMBER = AL3.EMPLOYEE_NUMBER
AND AL3.RECORDTYPE = 'DEPARTMENT_NUMBER'
AND AL7.DEPT_NBR = AL3.RECORDVALUE
) dt
ORDER BY AL4.Employee_Number;
Edit: Ok, I noticed this is a overly complex version of a simple DENSE_RANK with different order, shortly before Gordon posted his answer :-)
dense_rank() over (partition by AL4.EMPLOYEE_NUMBER order by AL7.POD_NBR)
Upvotes: 0
Reputation: 1269753
The function you are looking for is the analytic function dense_rank()
:
dense_rank() over (partition by eenbr order by pod) as ranking
This is the simplest way to get what you want. You can just add it in the select
clause of your query.
Upvotes: 2