0

Below is my table students (having 100K+ rows in orignal, showing just a set):

id name class marks
1 Ryan 5 8
2 Max 5 7
3 Max1 5 10
4 Ryan1 6 8
5 Max2 6 10
6 Ryan2 6 7
7 Ryan3 7 8
8 Max3 7 10
9 Ryan4 7 7

I want to fetch two rows per class ( 5 & 7) having marks <= 10 , also sorted by class, marks ASC

So, the expected result will be:-

id name class marks
1 Ryan 5 8
3 Max1 5 10
7 Ryan3 7 8
8 Max3 7 10

To execute below I tried:-

SELECT DISTINCT t_out.class, t_top.marks, t_top.name 
FROM students t_out 
  JOIN LATERAL (
    select * 
    from students t_in 
    where t_in.class = t_out.class 
    ORDER BY t_in.id ASC
  ) t_top ON TRUE 
WHERE t_top.marks <= 10 
 AND (t_out.class = 5 OR t_out.class = 7) 
ORDER BY t_top.marks DESC LIMIT 2;

Result on original database:- it's loading since long time

Result on sample :- Error: near line 20: near "(": syntax error

Is 10 the highest marks?

1
  • The ORDER BY in the derived table (sub-query) is pretty much useless. Commented Aug 28, 2021 at 17:53

1 Answer 1

1

You would use row_number():

select s.*
from (select s.*,
             row_number() over (partition by class order by marks desc) as seqnum
      from students s
      where marks < 10 and class in (5, 7)
     ) s
where seqnum <= 2
order by class, marks;

Note: Your question is a little confusing. You seem to want two rows with the highest marks per class ordered in descending order by marks.

EDIT:

Based on your comment:

select s.*
from (select s.*,
             row_number() over (partition by class order by marks desc) as seqnum,
             count(*) over (partition by class) as cnt
      from students s
      where marks < 10 
     ) s
where seqnum <= 2 and cnt >= 2
order by class, marks;
Sign up to request clarification or add additional context in comments.

6 Comments

Is latrel not faster than window? I'll give try for this on my main table
There are 99% possibility that in original database 10 marks is not highest and 7 is not lowest. And that's why query will be fetched DESC but output should be in ASC
@Slook . . . You would need to test on your data, but appropriate indexes for filtering is probably the key to performance.
a small query, why we are not using seqnum = 2 ? As I want to exclude those class where class is having only 1 row (suppose here class 7)
@Slook . . . Check out the edit. I didn't realize that was how you wanted to filter the classes.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.