Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the Highest, then the lowest, then the 2nd higest, and then the 2nd lowest value and so on from a table

I've a question, how can I get the highest value, then the lowest value, then the second highest value from a table.

For example: in the table

Name        Value
----------------------
Apple        2
Pear         3
Pineapple    6
Mango        7
Kiwi         1

Result should look like this:

Name           Value
-----------------------
Mango           7
Kiwi            1
Pineapple       6
Apple           2
Pear            3

Thanks!

like image 947
Dario M. Avatar asked May 14 '13 13:05

Dario M.


1 Answers

I'm assuming the tsqlt tag was meant to be tsql, and further that this implies that this is for SQL server:

;with Numbered as (
    select Name,Value,
        ROW_NUMBER() OVER (ORDER BY Value DESC) as rnDesc,
        ROW_NUMBER() OVER (ORDER BY Value ASC) as rnAsc
    from
        @t
), MixedNumbered as (
    select
        Name,Value,
        CASE WHEN rnDesc < rnAsc THEN rnDesc ELSE rnAsc END as rnFin,
        rnAsc,
        rnDesc
    from
        Numbered
)
select Name,Value from MixedNumbered order by rnFin,rnDesc

This works by finding the row numbers whilst considering the list sorted both highest-to-lowest and lowest-to-highest (in Numbered, rnDesc and rnAsc). We then take the lowest row number that was achieved when considering either of these orderings (MixedNumbered, rnFin).

This should then, produce two rows with an rnFin equal to 1, two rows with it equal to 2, and so on; pairing the nth highest and nth lowest rows until we reach the middle of the set.

We then use this to sort the final result set - but use the position obtained by considering the values sorted highest-to-lowest (rnDesc) as the tie breaker between each pair of rows with the same rnFin value. This means, for each pair, that the higher valued row will appear first.

To reverse the result (lowest first, then highest, the second lowest, second highest, etc), we need only change the final ORDER BY clause to rnFin,rnAsc.

like image 147
Damien_The_Unbeliever Avatar answered Oct 03 '22 15:10

Damien_The_Unbeliever