UNION ALL是否保证结果集的顺序?



我能确定下面脚本的结果集总是这样排序吗?

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

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

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

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

您不能保证订单,除非您通过查询明确提供订单。

不,它没有。SQL表本质上是无序的。你需要使用order by来获得所需的顺序。

问题不在于当你尝试它时它是否工作一次。问题是您是否可以信任此行为。你不能。SQL Server甚至不能保证this的顺序:

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

这里写着:

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

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

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

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

我将用大写字母表示,以便更清楚:

你不能保证没有order BY

的订单

进一步阅读:

  • 要改掉的坏习惯:依赖未记录的行为

另外,请阅读Conor Cunningham的这篇文章,他是SQL团队中一个非常聪明的家伙。

No。您可以以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

最新更新