没有ORDER BY的Where子句中的SQL Row_Number()函数?

时间:2011-06-17 18:35:55

标签: sql sql-server database

我在这个主题上发现了很多问题并提供了很好的解决方案,但是如果不以某种特定的方式对数据进行排序,它们实际上都没有解决该怎么做。例如,以下查询:

WITH MyCte AS 
(
    select   employee_id,
             RowNum = row_number() OVER ( order by employee_id )
    from     V_EMPLOYEE 
    ORDER BY Employee_ID
)
SELECT  employee_id
FROM    MyCte
WHERE   RowNum > 0

如果要由employee_id订购数据,则效果很好。但是,如果我的数据没有任何特定的顺序,但行号本身作为ID怎么办?我的目标是编写一个这样的查询(Row_Number()函数没有ORDER BY子句):

WITH MyCte AS 
(
    select   employee_id,
             RowNum = row_number() OVER ( <PRESERVE ORIGINAL ORDER FROM DB> )
    from     V_EMPLOYEE 
    ORDER BY Employee_ID
)
SELECT  employee_id
FROM    MyCte
WHERE   RowNum > 0
编辑:通过谷歌搜索,我发现这是不可能的。有人可以为此建议解决方法吗?

5 个答案:

答案 0 :(得分:92)

以防万一对其他人有用。我只是从elsewhere中找到了它:

WITH MyCte AS 
(
    select   employee_id,
             RowNum = row_number() OVER (ORDER BY (SELECT 0))
    from     V_EMPLOYEE 
    ORDER BY Employee_ID
)
SELECT  employee_id
FROM    MyCte
WHERE   RowNum > 0

答案 1 :(得分:21)

我用它来抑制排序:

ORDER BY @@rowcount

@@ rowcount在查询中是常量。例如:

select N = row_number() over (order by @@rowcount) from sys.columns

在ORDER BY中使用(选择0)似乎运行得慢得多。

答案 2 :(得分:6)

您提出的方法的真正问题是无法保证数据库中的顺序。它可能巧合地一直以相同的顺序返回到您的应用程序,但SQL标准保证不会有这样的顺序,并且可能会根据版本或版本更改而更改。如果没有order by子句,则无法保证来自SQL Server的数据顺序。这种设计只是依赖于“运气”。如果顺序中的这种可能的变化会对您的实现产生影响,那么您可能需要在实施过程中进行更改。

Good article on this topic

答案 3 :(得分:4)

没有ORIGINAL ORDER这样的东西。如果未指定ORDER BY,则SQL Server无法保证行的顺序。您可能会很幸运并按特定顺序获得结果,但它可能会随时更改。

答案 4 :(得分:1)

有一个比上面简单的解决方案。您仍然可以使用ROW_NUMBER,但在Order by子句中提供任意值:

Select firstName, lastName, ROW_NUMBER() OVER (ORDER BY (SELECT 1)) from tblPerson