47

我可以确定以下脚本的结果集将始终像这个 ORDER 那样排序吗?

SELECT 'O'
UNION ALL
SELECT 'R'
UNION ALL
SELECT 'D'
UNION ALL
SELECT 'E'
UNION ALL
SELECT 'R'

是否可以证明有时顺序不同?

4

4 回答 4

54

没有固有的顺序,你必须使用ORDER BY. 对于您的示例,您可以通过SortOrder在每个 SELECT 中添加一个来轻松地做到这一点。然后,这将按照您想要的顺序保留记录:

SELECT 'O', 1 SortOrder
UNION ALL
SELECT 'R', 2
UNION ALL
SELECT 'D', 3
UNION ALL
SELECT 'E', 4
UNION ALL
SELECT 'R', 5
ORDER BY SortOrder

除非您通过查询明确提供订单,否则您无法保证订单。

于 2013-04-02T14:15:13.437 回答
40

不,不是的。SQL 表本质上是无序的。您需要使用order by以按所需顺序获取事物。

问题不在于您试用时它是否有效。问题是您是否可以信任这种行为。而你不能。SQL Server 甚至不保证这个顺序:

select *
from (select t.*
      from t
      order by col1
     ) t

在这里说:

在视图、内联函数、派生表或子查询的定义中使用 ORDER BY 时,该子句仅用于确定 TOP 子句返回的行。当查询这些构造时,ORDER BY 子句不保证有序的结果,除非在查询本身中也指定了 ORDER BY。

SQL 语言的一个基本原则是表没有顺序。因此,尽管您的查询可能适用于许多数据库,但您应该使用 BlueFeet 建议的版本来保证结果的顺序。

于 2013-04-02T14:13:00.423 回答
16

例如,尝试删除所有ALLs。或者甚至只是其中之一。SELECT现在考虑当查询是针对表的实际查询并单独优化时,必须在那里发生的优化类型(以及许多其他类型)也是可能的。如果没有ORDER BY, 每个查询中的排序将是任意的,并且您不能保证查询本身将以任何顺序处理。

UNION ALL说不ORDER BY就好像说“把所有的弹珠都扔在地板上” 。也许每次你把所有的弹珠都扔在地板上时,它们最终都会按颜色排列。这并不意味着下次您将它们扔到地板上时,它们的行为也会相同。SQL Server 中的排序也是如此 - 如果您不说ORDER BY,那么 SQL Server 假定您不关心顺序。你可能会碰巧看到某个订单一直被返回,但很多事情都会影响一次选择的任意订单。数据更改、统计数据更改、重新编译、计划刷新、升级、服务包、修补程序、跟踪标志……令人作呕。

为了清楚起见,我将用大写字母表示:

您不能保证没有 ORDER BY 的订单

一些进一步的阅读:

另外,请阅读 SQL 团队中非常聪明的人 Conor Cunningham 的这篇文章

于 2013-04-02T14:28:18.237 回答
6

不,您可以通过 SQL Server 为您获取记录的任何方式获取记录。因此,您可以通过基于 1 的索引对联合结果集应用订单:

SELECT 1, 'O'
UNION ALL
SELECT 2, 'R'
UNION ALL
SELECT 3, 'D'
UNION ALL
SELECT 4, 'E'
UNION ALL
SELECT 5, 'R'
ORDER BY 1
于 2013-04-02T14:14:27.573 回答