如何通过条款获得所有订单的固定订单?

时间:2017-04-10 13:27:28

标签: sql sql-server

我想返回一个值,表示返回集合中每个结果的行号。即我希望结果好像我使用row_number()函数,并在order by窗口中匹配语句的order by子句。

select *
, row_number() over (order by /*order by columns*/) [row_number]
from someTable
order by /*the same columns in the same order as given above*/

但是,我只想更改order by子句;不是窗口函数中的值。

3 个答案:

答案 0 :(得分:0)

确定。这样做

SELECT *,ROW_NUMBER () OVER (ORDER BY Col1) AS [Order] 
FROM   @Table 
ORDER BY [Order]

答案 1 :(得分:0)

有不同的方法来实现这一目标;虽然没有一个是完美的:

1)在行号窗口中指定顺序,然后按行号排序:

SELECT 
    *
    ,ROW_NUMBER() OVER (ORDER BY col2) AS [Order]
FROM 
    @Table 
ORDER BY 
    [order]

即。这允许您在一个地方指定order by值,同时[order]列和结果的顺序匹配;但是通过在查询的不同部分指定顺序来实现。

这并不完全符合您的要求,但可能是合适的(例如,如果您的情况是您不希望因条款错误维护/由于程序员错误而意外地不同步而导致您的2个订单冒险)。 / p>

2)以编程方式指定订单。这可以通过调用语句的任何代码或使用动态SQL来完成。

declare @sql nvarchar(max)
, @orderByStatement nvarchar(max)

set @orderByStatement = 'col2, col1'

set @sql = '
SELECT 
    *
    ,ROW_NUMBER() OVER (ORDER BY ' + @orderByStatement + ') AS [Order]
FROM 
    #Table --NB: would need to use a real or temp table rather than table variable to have this be visible to the dynamic SQL statement
ORDER BY ' + @orderByStatement 

exec (@sql)

如果您以编程方式修改order by子句并希望确保窗口函数适应它,这将非常有用。 注意:您可能需要添加逻辑来处理没有给出订单的特殊情况;使用默认订单,或声明&按固定值变量排序。

这可以与建议#1一起使用;仅动态替换窗口的order-by子句,然后按该编号对结果进行排序。

摘要/问题

您选择哪种方法取决于您的要求;那你为什么采取这种方法?我的猜测是你正在使用一个允许你设置一个固定查询的框架,只允许你在运行时修改ORDER BY子句。遗憾的是,对于这种情况,上述情况都不会奏效。接受的答案(即通过固定值变量排序)通常可以起作用(可能),但不能保证;所以可能是可以接受的,这取决于这个值的重要性/当这个值与预期值不同时会发生什么的影响。

答案 2 :(得分:-1)

如果我理解正确,您希望获得行编号,而无需在ORDER BY函数的ROW_NUMBER子句中明确提供要排序的列。试试这个:

INSERT INTO @Table
    SELECT 1,'a' UNION ALL
    SELECT 2,'c' UNION ALL
    SELECT 2,'f' UNION ALL
    SELECT 4,'a' UNION ALL
    SELECT 10,'a'

SELECT 
    *,
    ROW_NUMBER() OVER (ORDER BY (select 1)) AS [Order] 
FROM 
    @Table 
ORDER BY 
    col1

<强>更新

另一种可能更加一致的方法是为ROW_NUMBER函数添加一个虚拟列和顺序:

SELECT 
    *,
    ROW_NUMBER() OVER (ORDER BY dummy) AS [Order] 
FROM 
    (select 0 dummy, * from @Table ) t
ORDER BY 
  col2