如何使用 UNION 组合两个具有 ORDER BY 的查询?

Posted

技术标签:

【中文标题】如何使用 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 生成的输出集中,列称为titlecontent。这些是order byunion all 识别的名称。 我明白你的意思,但请看顺序:id, name, title, contentid, tag, question, answer。那么title, contentquestion, answer 相同。但实际上我需要tag 而不是answer。不幸的是,使用外部order by (我认为) 是不可能实现的

以上是关于如何使用 UNION 组合两个具有 ORDER BY 的查询?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 SQLite 使用 UNION ALL 和 ORDER BY 进行排序

为啥在mysql中第一个union两个子句的order by不起作用

如何通过 HSQLDB 和 MySQL 之间的差异来处理 union/order?

MYSQL使用Union来组合两个查询

如何在 union all 中使用 order by

order by 和union all 如何共存