5

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!

4

3 回答 3

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

这通过查找行号来工作,同时考虑从最高到最低和最低到最高(在 和 中)排序NumberedrnDesc列表rnAsc。然后,我们采用在考虑这些排序中的任何一个时达到的最低行数 ( MixedNumbered, rnFin)。

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

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

要反转结果(首先是最低,然后是最高,次低,次高等),我们只需将最后一个ORDER BY子句更改为rnFin,rnAsc.

于 2013-05-14T13:25:57.203 回答
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

SQL Fiddle 的示例。

于 2013-05-14T13:32:52.447 回答
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
于 2013-05-20T12:23:20.950 回答