Reputation: 2698
Suppose we have two Tables: 1. Student 2. Department
Student table has 4 columns
1. id (int pk)
2. name (varchar)
3. percentage (int)
4. dept_id (fk)
Department table has 3 columns
1. dept_id (int pk)
2. dept_name (varchar)
Query is to select top 3 students from the each department having highest percentage.
I have already written the query with row_num() function.
But, I am facing problem when there are students with the same percentage.
Student table with:
id name percentage dept_id
1 a 70 1
2 b 80 1
3 c 90 1
4 d 70 1
5 e 55 1
6 f 50 2
7 g 65 2
8 h 68 2
Department table with
dept_id dept_name
1 Information Technology
2 Computer Science
**expected Result**
id student_name dept_name percentage row_number
3 c Information Technology 90 1
2 b Information Technology 80 2
1 a Information Technology 70 3
4 d Information Technology 70 4
8 h Computer Science 68 5
7 g Computer Science 65 6
6 f Computer Science 50 7
you can see that, there are two student with 70% so both the student will be considered at the third place, and will be a part of top 3.
I have tried something like
SELECT *, ROW_NUM() OVER (PARTITION BY D.Dept_ID ORDER BY S.PERCENTAGE DESC) AS ROW_NUMBER
FROM STUDENT S, DEPARTMENT D WHERE D.DEPT_ID = S.DEPT_ID
)
SELECT ID, NAME AS STUDENT_NAME, DEPT_NAME, PERCENTAGE FROM CTE WHERE ROW_NUMBER < 4.
HERE, I am adding static condition (row_number < 4) row_number, It will give me a wrong output when there are students with the same percentage.
Please help with this.
Upvotes: 1
Views: 2250
Reputation: 16908
You can try with DENSE_RANK() instead off ROW_NUMBER() as below-
SELECT A.dept_id,A.name,A.dept_name,A.percentage
FROM
(
SELECT D.dept_id,S.name,D.dept_name,S.percentage,
DENSE_RANK() OVER(PARTITION BY D.dept_id ORDER BY S.[percentage] DESC) RN
FROM Department D
INNER JOIN Student S ON D.dept_id = S.dept_id
)A
WHERE RN <= 3
Output is-
dept_id name dept_name percentage
1 c Information Technology 90
1 b Information Technology 80
1 d Information Technology 70
1 a Information Technology 70
2 h Computer Science 68
2 g Computer Science 65
2 f Computer Science 50
Upvotes: 1
Reputation: 1269733
Is this the query you are trying to write?
WITH cte as (
SELECT s.ID, s.NAME, d.DEPT_NAME, s.PERCENTAGE,
RANK() OVER (PARTITION BY D.Dept_ID ORDER BY S.PERCENTAGE DESC) AS seqnum
FROM STUDENT S JOIN
DEPARTMENT D
ON D.DEPT_ID = S.DEPT_ID
)
SELECT cte.ID, cte.NAME AS STUDENT_NAME, cte.DEPT_NAME, cte.PERCENTAGE
FROM CTE
WHERE seqnum < 4;
Notes:
FROM
clause.JOIN
syntax.ROW_RANK()
is not a function. I think you want RANK()
, given that you want four rows when the limit is just 3.Upvotes: 5