订购sql查询结果

时间:2010-05-17 20:15:16

标签: sql sql-server sql-server-2005

我的sql查询给出了列:

  • product_id(这是一个整数)
  • pnl(浮动 - 可以是否定的)

我获得超过100行。

我想基于abs(pnl)过滤掉前40行。 但结果应仅按pnl列排序,而不是按abs(pnl)排序。

我想为MSSQL 2005做这件事。

有办法做到这一点吗?

3 个答案:

答案 0 :(得分:7)

您无法在一个步骤/法规中执行此操作。 TOP x选择将始终基于ORDER BY排序指令。您无法根据ABS(pnl)选择TOP 40,同时也可以按其他方式选择。

您需要做的是两步过程 - 使用CTE(公用表表达式)或临时表 - 首先选择由ABS(pnl)排序的前40行,然后按{命令结果集} {1}}。

类似的东西:

pnl

答案 1 :(得分:3)

假设product_id不是表的主键,您可以执行以下操作:

Select ...
From Table
    Join    (
            Select TOP 40 TablePK
            From Table
            Order by Abs( pnl ) Desc
            ) As Z
        On Table.TablePK = Z.TablePK
Order By Table.pnl ASC      

正如提到的OMG Ponies,您可以将其作为单个派生表来执行:

Select ...
From (
        Select TOP 40 .....
        From Table
        Order by Abs( pnl ) Desc
        ) As Z
Order By Z.pnl ASC      

如果您想使用CTE,那么我会使用ROW_NUMBER函数执行此操作:

With RankedItems As
    (
    Select ...
        , ROW_NUMBER() OVER ( ORDER BY Abs(Table.pnl) ) As ItemRank
    From Table
    )
Select 
From RankedItems
Where ItemRank <= 40
Order By pnl ASC

答案 2 :(得分:0)

为了完整起见,这与@marc_s相同,但不使用CTE:

SELECT product_id, pnl FROM (
    SELECT TOP 40 product_id, pnl FROM tbl ORDER BY abs(pnl) ) x 
ORDER BY pnl