如何获得最高,然后是最低,然后是第二高,然后是第二个最低值,依此类推

时间:2013-05-14 13:12:24

标签: sql sql-server tsql

我有一个问题,我如何获得最高值,然后是最低值,然后是表格中的第二高值。

例如:在表格中

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

结果应如下所示:

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

谢谢!

3 个答案:

答案 0 :(得分:10)

我假设tsqlt标记应该是tsql,而且这意味着这是针对SQL服务器的:

;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

这可以通过查找行号同时考虑列表从最高到最低和从最低到最高(NumberedrnDescrnAsc)进行排序。然后,我们考虑在考虑这些排序中的任何一个时获得的最低行数(MixedNumberedrnFin)。

然后,应该生成两行rnFin等于1,两行等于2,依此类推;将 n 最高行和 n 最低行配对,直到我们到达集合的中间位置。

然后我们使用它来对最终结果集进行排序 - 但是使用通过考虑从最高到最低(rnDesc)排序的值获得的位置作为每对行之间具有相同{{{{ 1}}价值。这意味着,对于每一对,较高值的行将首先出现。

要反转结果(最低,然后是最高,第二低,第二高等),我们只需将最终rnFin子句更改为ORDER BY

答案 1 :(得分:4)

这将数字2分配给最大的行,3分配给最小的行,4分配给第二大的行,依此类推。

select  *
from    (
        select  1 + 2 * row_number() over (order by Value asc) as rnAsc
        ,       2 * row_number() over (order by Value desc) as rnDesc
        ,       t1.*
        from    Table1 t1
        ) SubQueryAlias
order by
        case
        when rnDesc < rnAsc then rnDesc
        else rnAsc
        end

Example at SQL Fiddle.

答案 2 :(得分:0)

一个很棒的问题! 请检查我的尝试:

SELECT Name,Value
FROM(
    SELECT *, MAX(Rnum) OVER() mx, MAX(Rnum) OVER()/2.0 hf FROM(
        SELECT *, ROW_NUMBER() OVER(ORDER BY value DESC) Rnum From @tbl
    )x
)xx
ORDER BY CASE WHEN Rnum-hf<=0 THEN Rnum ELSE mx-Rnum+1 END, Rnum