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

why*_*heq 40 sql sql-server

我可以确定以下脚本的结果集将始终按此ORDER进行排序吗?

SELECT 'O'
UNION ALL
SELECT 'R'
UNION ALL
SELECT 'D'
UNION ALL
SELECT 'E'
UNION ALL
SELECT 'R'
Run Code Online (Sandbox Code Playgroud)

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

Tar*_*ryn 48

没有固有的顺序,你必须使用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
Run Code Online (Sandbox Code Playgroud)

除非您通过查询专门提供订单,否则您无法保证订单.

  • @whytheq在徒步旅行中没有看到树林里的熊并不意味着树林里没有熊.即使订单*可以保证,你从中获得了什么呢?在这个特定情况下不必输入`ORDER BY`?这样可以为你节省大量的工作效率.<耸肩> (7认同)
  • 我从来没有见过有人在交通事故中被挡风玻璃扔过,但为了以防万一,我仍然系好安全带.它是免费的,没有伤害,并保证结果(没有挡风玻璃投掷). (6认同)
  • 我听到有很多人说它不会总是按照相同的顺序和各种文档,但没有经验证据 - 我希望能够运行查询并看到它实际上以不同的顺序吐出结果. (2认同)

Gor*_*off 37

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

问题不在于你试用它是否有效.问题是您是否可以信任此行为.你不能.SQL Server甚至不保证这个的排序:

select *
from (select t.*
      from t
      order by col1
     ) t
Run Code Online (Sandbox Code Playgroud)

在这里说:

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

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

  • @whytheq - 看起来可能相同,但有时第二个字母和第五个字母会改变位置. (5认同)
  • 不要考虑离散机器.从集合的角度思考.如果需要订购,您必须明确地声明集合的顺序,否则它只是一行行. (4认同)
  • @whytheq--这是一种玩笑,但也有一个严肃的观点 - 即使在你的有限测试中,你有两行在结果集中显得相同 - 所以即使在你的测试中,你也没有证明第二个结果来自第二个查询,第五个查询的第五个结果 - 它可能是另一种方式,你的观察仍然是一致的. (3认同)

Aar*_*and 16

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

UNION ALL没有ORDER BY好像是说"就扔在地板上所有的大理石." 也许每当你把所有弹珠扔在地板上时,它们最终都是按颜色组织的.这并不意味着下次你将它们扔到地板上时它们的行为方式相同.对于SQL Server中的排序也是如此 - 如果您没有说,ORDER BY则SQL Server假定您不关心订单.您可能会巧合地看到一直在返回某个订单,但很多事情都会影响下次选择的任意订单.数据更改,统计信息更改,重新编译,计划刷新,升级,Service Pack,修补程序,跟踪标记... ad nauseum.

我会用大写字母说清楚:

如果没有ORDER BY,您无法保证订单

进一步阅读:

此外,请阅读Conor Cunningham的这篇文章,他是SQL团队中一个非常聪明的人.

  • @bluefeet只有链接到SQLfiddle.:-) (3认同)
  • 你能让那个字体变得更大我不明白吗?:) (2认同)
  • @whytheq没有喊叫.如果我大喊大叫,那将是全部大写.我试图以最简单的形式提出答案 - 对未来的读者来说是完全明显的. (2认同)

Pau*_*sik 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
Run Code Online (Sandbox Code Playgroud)

  • 您应该将列别名应用于第一列并按此顺序排序.[顺序位置排序是一个坏习惯](http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/06/bad-habits-to-kick-order-by-ordinal.aspx)工作正常在这里,但可能在别处打破 (6认同)
  • ORDER现在拼写为"错误",因为排序是按字母顺序排列的.如果添加数字索引,则可以强制进行"正确"拼写.请参阅上面的编辑. (3认同)