UNION、TOP、ORDER BY联合使用时处理顺序是啥?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UNION、TOP、ORDER BY联合使用时处理顺序是啥?相关的知识,希望对你有一定的参考价值。
首先,TOP n好像不是SQL标准,但大多数DBMS产品支持这个特性。
我看到SQL Server的介绍,TOP的逻辑处理顺序在ORDER BY后面,也就是先排序然后取前n个,这应该是很正常的需要,要是先取前几个再排序,排序就失去存在的理由了。UNION多个查询时,ORDER BY只能出现在最后,是对集合操作的表联合到一起再排序,这个顺序来处理,也很好理解。
但问题随之来了,当用UNION连接多个SELECT时,每个都有一个TOP n,并且n不相同,最后再有一个ORDER BY,那么,顺序是什么样的?如果是先UNION,再ORDER BY,再TOP,那么怎么保证UNION后知道每条记录都分别是哪张表上的呢?重行已经消除掉了,TOP n怎么来保证呢?如果先是ORDER BY,再TOP,再UNION,那UNION后又无序了,难道会是先ORDER BY,再TOP,再UNION,再ORDER BY,做两次ORDER BY?
如果大家有官方说法或较大的网站上的引用,请尽量给出,谢谢。
有两条这样的语句:(假设A与B的字段数一样)
Select * From A
Select * From B
如果利用Union,要查出两个条中按RecID前10条的记录.
想到的第一种方法就是:
Select Top 5 * From A
Union
Select Top 5 * From B
Order By RecID
但其实这种方法是有问题的...因为A表并没有按照RecID来排序,但又不可以写成这样
Select Top 5 * From A
Order By RecID
Union
Select Top 5 * From B
Order By RecID
所以我个人平时用的方法就是:
Select Top 10 * From
(
Select * From A
Union All
Select * From B
)
A Order By RecID
虽然我也没有去官方的网站上看过这种问题,但我用到现在,我个人方法还是没有出现过错误.. 参考技术A (select top 9 * from table1 order by id)
union
(select top 19 * from table2 order by id)
union
(select top 99 * from table3 order by id)
你如果想union之后再order by的话得使用子查询本回答被提问者采纳
如何使用 UNION 组合两个具有 ORDER BY 的查询?
【中文标题】如何使用 UNION 组合两个具有 ORDER BY 的查询?【英文标题】:How to combine two queries that have ORDER BY using UNION? 【发布时间】:2015-10-15 13:14:16 【问题描述】:我有两个查询,它们每个都有自己的order by
,如下所示:
查询1:
SELECT id, name, title, content
FROM table where match(title, content) against('anything')
Order By title
查询1:
SELECT id, tag, question, answer
FROM table
Where tag like '%anything'
Order By tag, question
现在如何使用UNION ALL
组合它们?
【问题讨论】:
您希望结果如何排序? 【参考方案1】:您需要对结果进行排序:
-
结果类型(匹配或喜欢)
标题(MATCH)或标签(LIKE)
NULL(对于 MATCH)或 question(对于 LIKE)
您可以使用嵌套查询:
SELECT * FROM (
SELECT 1 AS result_type, id, name, title, content
FROM table
WHERE MATCH (title, content) AGAINST ('anything')
UNION ALL
SELECT 2, id, tag, question, answer
FROM table
WHERE tag LIKE '%anything'
) AS foobar
ORDER BY
result_type,
CASE result_type WHEN 1 THEN title ELSE tag END,
CASE result_type WHEN 1 THEN NULL ELSE question END
或者您可以添加排序辅助列:
(
SELECT 1 AS sort_1, title AS sort_2, NULL AS sort_3, id, name, title, content
FROM table
WHERE MATCH (title, content) AGAINST ('anything')
) UNION ALL (
SELECT 2 AS sort_1, tag AS sort_2, question AS sort_3, id, tag, question, answer
FROM table
WHERE tag LIKE '%anything'
)
ORDER BY sort_1, sort_2, sort_3
【讨论】:
虽然感觉这个查询没有优化。但这是唯一的解决方案。 您可以添加假列(以帮助排序)并避免嵌套查询。但是不能保证它是否会使查询更快。【参考方案2】:如果您想保持相同的顺序,那么以下通常有效:
(SELECT id, name, title, content
FROM table
where match(title, content) against('anything')
order by title
) union all
(SELECT id, tag, question, answer
FROM table
where tag like '%anything'
order by tag, question
);
这在实践中有效,因为实际上第一个子查询在第二个子查询之前执行。但是,我认为 MySQL 文档并不能保证两者的处理顺序。为了保证,你需要一个外部的order by
:
(SELECT id, name, title, content, 1 as priority
FROM table
where match(title, content) against('anything')
) union all
(SELECT id, tag, question, answer, 2 as prioirty
FROM table
where tag like '%anything'
)
ORDER BY priority, title, content
【讨论】:
您的第二个查询不完整。因为没有ORDER BY tag, question
。无论如何+1
@Sajad 。 . .当然不是。在union all
生成的输出集中,列称为title
和content
。这些是order by
为union all
识别的名称。
我明白你的意思,但请看顺序:id, name, title, content
和 id, tag, question, answer
。那么title, content
与question, answer
相同。但实际上我需要tag
而不是answer
。不幸的是,使用外部order by
(我认为) 是不可能实现的以上是关于UNION、TOP、ORDER BY联合使用时处理顺序是啥?的主要内容,如果未能解决你的问题,请参考以下文章
UNION ALL、TEXT 字段和 ORDER BY 错误
如何使用 Union 、 Order By 和 Rownum?
在 Toad for Sql Server 2016 中使用带有 Union All 的 Order By 子句时出现奇怪的语法错误