【问题标题】:Unexpected SQL Behaviour with "SELECT TOP" Query“SELECT TOP”查询的意外 SQL 行为
【发布时间】:2019-11-09 23:19:06
【问题描述】:

我使用的是 Microsoft SQL Server 2019,当我执行时:

SELECT TOP 10 *
FROM  WideWorldImporters.Sales.Invoices

SELECT TOP 10 CustomerID
FROM  WideWorldImporters.Sales.Invoices

它给出了结果:

这是不正确的,因为这些不是第一个查询显示的“前 10 个”客户 ID。

全屏截图:

编辑:我预期的上述行为与 SQL Sever 2014 中实际发生的情况相符。我怀疑他们更改了 SQL Server 2019 中的底层实现,尽管它仍然满足记录的行为。

【问题讨论】:

标签: sql sql-server tsql select ssms


【解决方案1】:

没有 ORDER BY 的 TOP 是不可预测的。这由 Microsoft 记录。来自Microsoft docs

当您将 TOP 与 ORDER BY 子句一起使用时,结果集仅限于前 N 个有序行。否则,TOP 以未定义的顺序返回前 N 行。

...

在 SELECT 语句中,始终将 ORDER BY 子句与 TOP 子句一起使用。因为,它是可预测地指示哪些行受 TOP 影响的唯一方法。

另见how does SELECT TOP works when no order by is specified?

【讨论】:

  • 在文档的最佳实践部分中,他们说:“在 SELECT 语句中,始终使用带有 TOP 子句的 ORDER BY 子句。因为,这是可预测地指示哪些行受到影响的唯一方法最佳。”但是当我右键单击一个表并选择“选择前 1000 行”时,我得到一个不包含 ORDER BY 的 SELECT TOP 查询。嘘……
【解决方案2】:

您没有ORDER BY,因此将返回按不确定顺序排列的前 10 个结果。此顺序可以从一个执行更改为下一个执行。

SQL 中的表表示无序 集合。如果您想要使用TOP 的特定行,您需要有一个ORDER BY

【讨论】:

    【解决方案3】:

    评论太长了。

    在 SQL 中,表记录是无序的。因此,像您这样的查询:

    SELECT TOP 10 * FROM  WideWorldImporters.Sales.Invoices
    

    ... 会产生不一致的结果,因为它缺少ORDER BY 子句。您需要告诉您的 RDBMS 应该使用哪一列来对记录进行排序,以便可以定义应该返回哪些 TOP 记录。例如,类似:

    SELECT TOP 10 * FROM  WideWorldImporters.Sales.Invoices ORDER BY InvoiceID DESC
    

    【讨论】:

    • 我预期的上述行为与 SQL Sever 2015 中实际发生的情况相符。我怀疑他们更改了 SQL Server 2019 中的底层实现,尽管它仍然满足“未定义顺序”的记录行为。跨度>
    【解决方案4】:

    这个结果是绝对正常的,因为您的查询没有指定顺序。前 10 个返回前 10 个结果。

    如果你不指定排序子句,结果会按照SQL引擎之前的操作返回,结果可能并不总是一样,也肯定不是你期望的结果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-30
      • 1970-01-01
      • 2011-01-03
      相关资源
      最近更新 更多