【问题标题】:SQL Row_Number() function in Where Clause without ORDER BY?没有 ORDER BY 的 Where 子句中的 SQL Row_Number() 函数?
【发布时间】:2011-06-17 18:35:55
【问题描述】:

我发现了一堆关于这个主题的问题,它们都有很好的解决方案,但没有一个真正涉及如果数据不是以一种特定的方式排序时该怎么做。例如,以下查询:

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

编辑:通过谷歌搜索,我发现这是不可能的。有人可以为此提出解决方法吗?

【问题讨论】:

  • 除非您有明确的ORDER BY 子句,否则在 SQL Server 环境中NO 隐式排序(没有“来自 DB 的原始订单”)
  • @marc_s:谢谢。澄清一下,您的意思是说,在一个包含 20000 条记录的小型数据库中,它不保留插入顺序(即使没有并发插入)?
  • @marc_s:+1 你是对的。即使在顺序插入期间,它也不会保留顺序。这与我的 MySQL 经验完全不同。感谢您的提醒!

标签: sql sql-server database


【解决方案1】:

以防万一它对其他人有用。我只是从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

【讨论】:

  • 如果您认为这是合适的答案,您应该这样标记。这样,问题将被正确标记为已回答,其他人可以更成功地找到此解决方案。
  • @mtazava:实际上,我想给它一些时间(无论如何它需要等待 2 天才能接受我自己的答案 :))。问题是,我不是 SQL Server 方面的专家,我听到一些人说这种方法本身不能被遵循,因为不能保证顺序。
  • ORDER BY (SELECT 0) 不保证正确排序。见stackoverflow.com/questions/9737131/sql-server-join-in-order
  • 是的,证明这行不通的一种简单方法是将V_EMPLOYEE 替换为有序派生表:stackoverflow.com/q/18961789/521799
  • (ORDER BY (SELECT 0)) 的真正含义是什么?
【解决方案2】:

我用它来抑制排序:

ORDER BY @@rowcount

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

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

在 ORDER BY 中使用 (select 0) 似乎要慢得多。

【讨论】:

    【解决方案3】:

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

    Good article on this topic

    【讨论】:

    • @Legend:我添加了一篇文章的链接,该文章讨论了 SQL Server 的结果集排序主题。
    【解决方案4】:

    没有原始订单之类的东西。如果不指定 ORDER BY,SQL Server 不能保证行的顺序。您可能会很幸运并按特定顺序获得结果,但它可能随时改变。

    【讨论】:

      【解决方案5】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-24
        • 2010-11-30
        • 2011-06-16
        • 2012-12-24
        • 1970-01-01
        • 2012-04-21
        • 2016-06-12
        相关资源
        最近更新 更多