使用 UNION 组合两个 SELECT 查询的 ORDER BY
Posted
技术标签:
【中文标题】使用 UNION 组合两个 SELECT 查询的 ORDER BY【英文标题】:Combined ORDER BY of two SELECT queries using UNION 【发布时间】:2021-11-19 05:40:43 【问题描述】:如何通过从这两个查询中检索到的结果获得组合顺序,并通过 UNION
连接?
SELECT u.id, u.name, u.gender, n.user, n.other_user, n.type, n.notification, n.membership, n.link, n.created_at, p.photo FROM notifications n
INNER JOIN users u ON
CASE
WHEN n.user = :me THEN u.id = n.other_user
WHEN n.other_user = :me THEN u.id = n.user
END
LEFT JOIN photos p ON
CASE
WHEN n.user = :me THEN p.user = n.other_user AND p.order_index = (SELECT MIN(order_index) FROM photos WHERE user = n.other_user)
WHEN n.other_user = :me THEN p.user = n.user AND p.order_index = (SELECT MIN(order_index) FROM photos WHERE user = n.user)
END
UNION
SELECT '', '', '', '', '', '', n.notification, n.membership, n.link, n.created_at, '' FROM notifications n WHERE type = 'admin'
我希望返回的记录按照 id
s 的降序排列。例如,如果第一个查询返回的记录是3,5,4,6,7
,第二个查询返回的记录是2,1,9
,那么所有的记录都应该像9,7,6,5,4,3,2,1
这样组合排序。
我试过这个:
SELECT * FROM
(
*THE WHOLE QUERY ABOVE*
) AS x
ORDER BY x.id
这没有返回正确的结果。它按降序排列第一个查询的结果7,6,5,4,3
,并按升序排列第二个查询的结果1,2,9
。它们是单独排序的,而不是一起排序的。我怎样才能将它们组合在一起为9,7,6,5,4,3,2,1
。
【问题讨论】:
只需在最后添加ORDER BY id DESC
。
等待...第二个查询为每个id
生成''
(空字符串)。你确定这是正确的吗?
id
是数字列还是 VARCHAR 列?如果它是 VARCHAR,则需要对其进行后处理并将其转换为数字,以使排序按预期工作。
@TheImpaler 它的数据类型是BIGINT
@TheImpaler 当您指出第二个查询用 ''
代替 id
时,我的脑海中闪过一抹亮光。我继续用n.id
替换第一个''
。有了这个,顺序确实发生了变化,但我仍然没有得到正确的结果。这次它返回了混合的结果。未按要求按正确的降序排列。此外,在更正此问题后,我什至尝试使用 ORDER BY x.id DESC
,但这也没有用。
【参考方案1】:
在两个查询中添加通知 ID 并为它们指定别名,因为您没有在表中使用别名(我猜)。然后只需使用“Thorsten Kettner”回答的通知 ID 的别名进行排序。
SELECT u.id as uid, n.id as nid, u.name, u.gender, n.user, n.other_user, n.type, n.notification, n.membership, n.link, n.created_at, p.photo FROM notifications n
INNER JOIN users u ON
CASE
WHEN n.user = :me THEN u.id = n.other_user
WHEN n.other_user = :me THEN u.id = n.user
END
LEFT JOIN photos p ON
CASE
WHEN n.user = :me THEN p.user = n.other_user AND p.order_index = (SELECT MIN(order_index) FROM photos WHERE user = n.other_user)
WHEN n.other_user = :me THEN p.user = n.user AND p.order_index = (SELECT MIN(order_index) FROM photos WHERE user = n.user)
END
UNION
SELECT '', n.id as nid, '', '', '', '', '', n.notification, n.membership, n.link, n.created_at, '' FROM notifications n WHERE type = 'admin'
ORDER BY nid DESC
【讨论】:
我之前问了几个问题,大部分都得到了你的回答。总是来救我;)非常感谢。像魅力一样工作:) 不客气 :) 但是,如果您仔细看一看并考虑一下,您会发现自己已经解决了答案。您说您使用created_at
字段正确订购对吗?如果您观察正确,那么您会看到n.created_at
在两个查询中都很常见。使用它,如果您稍微运行一下您的大脑,您就会意识到可以尝试使用n.id
。那是你的答案!你的正确答案就在你的手下,你必须意识到它。
是的,我一看到你的回答就意识到了这一点,我想把头撞在墙上,因为我没有得到这么简单的东西。
哈哈..大声笑..尽情享受吧:)
附带说明:这应该是 UNION ALL
而不是 UNION
,因为没有要删除的重复项。【参考方案2】:
您自己已经发现了问题;您混淆了用户 ID 和通知 ID。所以选择这两个,使用别名来区分哪个是哪个并排序:
select u.id as user_id, ..., n.id as notification_id, ...
from ...
union all
select ... from ...
order by notification_id;
【讨论】:
您的回答完成了 50% 的工作。他需要在两个查询中提供通知 id 才能给出准确的结果。让我发布一个明确的答案。 我不会说您的回答在技术上是错误的,但 OP 寻求组合结果,这意味着他需要以混合方式对两个查询的结果进行排序,但要根据 id 而不是分别为每个查询。要提供所需的结果,您需要将通知 ID 放在两个查询中以进行组合排序。 @RedStar Entertainment:UNION [ALL]
查询在两个查询中都有相同的列。所以当然第二个查询也有notification_id。 ORDER BY
子句对组合查询的整个结果进行排序。
我同意@RedStarEntertainment,因为他的回答完成了这项工作。我也尝试过你的答案,但没有奏效。以上是关于使用 UNION 组合两个 SELECT 查询的 ORDER BY的主要内容,如果未能解决你的问题,请参考以下文章