SQL Server UNION - 默认 ORDER BY 行为是什么
如果我有一些 UNION 语句作为人为的示例:
SELECT * FROM xxx WHERE z = 1
UNION
SELECT * FROM xxx WHERE z = 2
UNION
SELECT * FROM xxx WHERE z = 3
默认的 order by
行为是什么?
我看到的测试数据本质上不会按顺序返回数据上面指定的。 即数据是有序的,但我想知道这方面的优先规则是什么。
另一件事是,在本例中 xxx 是一个视图。 该视图将 3 个不同的表连接在一起以返回我想要的结果。
If I have a few UNION Statements as a contrived example:
SELECT * FROM xxx WHERE z = 1
UNION
SELECT * FROM xxx WHERE z = 2
UNION
SELECT * FROM xxx WHERE z = 3
What is the default order by
behaviour?
The test data I'm seeing essentially does not return the data in the order that is specified above. I.e. the data is ordered, but I wanted to know what are the rules of precedence on this.
Another thing is that in this case xxx is a View. The view joins 3 different tables together to return the results I want.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
没有默认顺序。
如果没有 Order By 子句,则返回的订单是不确定的。 这意味着 SQL Server 可以按照它喜欢的任何顺序将它们恢复。
编辑:
根据我所看到的,如果没有 Order By,结果返回的顺序取决于查询计划。 因此,如果它正在使用一个索引,结果可能会按该顺序返回,但同样无法保证。
There is no default order.
Without an Order By clause the order returned is undefined. That means SQL Server can bring them back in any order it likes.
EDIT:
Based on what I have seen, without an Order By, the order that the results come back in depends on the query plan. So if there is an index that it is using, the result may come back in that order but again there is no guarantee.
关于添加 ORDER BY 子句:
这对于大多数人来说可能是基本的,但我想我添加了这个。
有时您不希望结果混合,因此您需要第一个查询的结果,然后是第二个查询的结果,依此类推。 为此,我只需添加一个虚拟的第一列并按其排序。 由于忘记给联合中的列起别名可能会出现问题,我通常在 order by 子句中使用序数,而不是列名。
例如:
当我要运行两个查询并且我知道只有一个查询会返回任何结果时,虚拟序数列也很有用。 然后我可以检查返回结果的序号。 这使我不必执行多个数据库调用和大多数空结果集检查。
In regards to adding an ORDER BY clause:
This is probably elementary to most here but I thought I add this.
Sometimes you don't want the results mixed, so you want the first query's results then the second and so on. To do that I just add a dummy first column and order by that. Because of possible issues with forgetting to alias a column in unions, I usually use ordinals in the order by clause, not column names.
For example:
The dummy ordinal column is also useful for times when I'm going to run two queries and I know only one is going to return any results. Then I can just check the ordinal of the returned results. This saves me from having to do multiple database calls and most empty resultset checking.
刚刚找到了真正的答案。
因为 UNION 会删除重复项,所以它会执行 DISTINCT SORT。 这是在连接所有 UNION 语句之前完成的(检查执行计划)。
要停止排序,请执行 UNION ALL,这也不会删除重复项。
Just found the actual answer.
Because UNION removes duplicates it does a DISTINCT SORT. This is done before all the UNION statements are concatenated (check out the execution plan).
To stop a sort, do a UNION ALL and this will also not remove duplicates.
如果您关心返回记录的顺序,则必须使用 order by。
如果您省略它,它可能看起来是有组织的(基于查询选择的索引)计划),但是您今天看到的结果可能不是您期望的结果,并且当明天运行相同的查询时它甚至可能会发生变化。
编辑:一些很好的具体示例:(所有示例都是 MS SQL Server)
Dave Pinal 的博客 描述了两个非常相似的查询如何因使用不同的索引而显示不同的表观顺序:
Conor Cunningham 显示当表格出现时表观顺序如何改变变得更大(如果查询优化器决定使用并行执行计划)。
Hugo Kornelis 证明了这一点表观顺序并不总是基于主键。 这是他的后续帖子和解释。< /p>
If you care what order the records are returned, you MUST use an order by.
If you leave it out, it may appear organized (based on the indexes chosen by the query plan), but the results you see today may NOT be the results you expect, and it could even change when the same query is run tomorrow.
Edit: Some good, specific examples: (all examples are MS SQL server)
Dave Pinal's blog describes how two very similar queries can show a different apparent order, because different indexes are used:
Conor Cunningham shows how the apparent order can change when the table gets larger (if the query optimizer decides to use a parallel execution plan).
Hugo Kornelis proves that the apparent order is not always based on primary key. Here is his follow-up post with explanation.
UNION 在结果集排序方面可能具有欺骗性,因为数据库有时会使用排序方法来提供 UNION 中隐含的 DISTINCT,这使得行看起来像是故意排序的 - 这不适用于 UNION ALL当然,这没有隐含的区别。
然而,有一些隐式不同的算法,例如 Oracle 在 10g+ 中的哈希方法,不会应用任何排序。
正如 DJ 所说,始终使用 ORDER BY
A UNION can be deceptive with respect to result set ordering because a database will sometimes use a sort method to provide the DISTINCT that is implicit in UNION , which makes it look like the rows are deliberately ordered -- this doesn't apply to UNION ALL for which there is no implicit distinct, of course.
However there are algorithms for the implicit distinct, such as Oracle's hash method in 10g+, for which no ordering will be applied.
As DJ says, always use an ORDER BY
经常会遇到编写糟糕的代码,这些代码假设表数据按插入顺序返回,并且 95% 的情况下,编码人员会侥幸逃脱,并且从未意识到这是一个问题,就像许多常见数据库(MSSQL、Oracle、 MySQL)。 这当然是一个完全的谬误,当遇到它时应该总是进行纠正,并且总是无一例外地自己使用 Order By 子句。
It's very common to come across poorly written code that assumes table data is returned in insert order, and 95% of the time the coder gets away with it and is never aware that this is a problem as on many common databases (MSSQL, Oracle, MySQL). It is of course a complete fallacy and should always be corrected when it's come across, and always, without exception, use an Order By clause yourself.