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

时间:2013-04-02 14:12:32

标签: sql sql-server

我可以确定以下脚本的结果集总是像O-R-D-E-R那样排序吗?

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

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

4 个答案:

答案 0 :(得分:45)

没有固有的顺序,您必须使用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

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

答案 1 :(得分:37)

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

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

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

它说here

  

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

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

答案 2 :(得分:16)

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

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

我会用大写字母说清楚:

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

进一步阅读:

另外,please read this post by Conor Cunningham, a pretty smart guy on the SQL team

答案 3 :(得分:5)

没有。您可以通过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