Brett
Brett

Reputation: 12007

SQL Query with ORDER BY Part 2

This is a followup question to: SQL Query with ORDER BY

But I think the SQL logic is going to be quite different, so I am posting it as separate question.

I am trying to extend my sql SELECT query it and having some trouble:

I have the table:

id    type      radius
-------------------------
1     type1     0.25
2     type2     0.59
3     type1     0.26
4     type1     0.78
5     type3     0.12
6     type2     0.45
7     type3     0.22
8     type3     0.98

and I am trying to learn how to SELECT the second smallest radius for each given type. So the returned recordset should look like:

id    type      radius
-------------------------
3     type1     0.26
2     type2     0.59
7     type3     0.22

(Note: in the referenced question, I was looking for the lowest radius, not the second lowest radius).

I am assuming I have to use LIMIT and OFFSET, but if I use the MIN() won't that return a distinct record containing the minimum radius?

Does anyone have any thoughts on how to attack this?

Many thanks, Brett

Upvotes: 3

Views: 164

Answers (3)

user330315
user330315

Reputation:

You didn't mention your DBMS, so I'll post a solution that works with DBMS that support the standard windowing functions:

SELECT *
FROM (
  SELECT id, 
         type,
         radius, 
         dense_rank() OVER (PARTITION BY type ORDER BY radius ASC) as radius_rank
  FROM radius_table
) t
WHERE radius_rank = 2

You can easily pick the 3rd lowest or 14th lowest as well by adjusting the WHERE condition

This solution will also work if you have more than one row that qualifies for 2nd lowest (the LIMIT solutions would only show one of them)

Upvotes: 2

Xavier Barbosa
Xavier Barbosa

Reputation: 3947

This query gives you the 2nd position of a given type

SELECT  *
FROM    `test`.`rads`
WHERE   type = 'type wanted'
ORDER BY `radius` ASC
LIMIT 1, 1

You can mix this in a subquery to fetche a whole list, like this query

SELECT  id, type, radius
FROM    `test`.`rads` t
WHERE   id = (
    SELECT  id
    FROM    `test`.`rads` ti
    WHERE   ti.type = t.type
    ORDER BY `radius` ASC
    LIMIT 1, 1)
ORDER BY radius ASC, id DESC

With this query you can vary the position by changing the LIMIT first parameter

Upvotes: 1

regilero
regilero

Reputation: 30496

I would use the SQL query from your previous answer and add a WHERE instrution in it removing all records containing the 'id' of the matching '1st lowest radius'.

SELECT t1.id,t1.type,t1.radius FROM table t1 
WHERE radius = ( 
     SELECT MIN(radius) FROM table
     WHERE radius = t1.radius
     AND id not IN (
       SELECT t2.id FROM table t2
       WHERE radius = ( 
         SELECT MIN(radius) FROM table
         WHERE radius = t2.radius
       )
     )
   )

Upvotes: 0

Related Questions