[英]Subquery using UNION ALL in MySQL
I guess I don't understand the order in which subqueries work.我想我不明白子查询的工作顺序。
When I run this SQL statement I get 1 (out of 3 that exist in the table) random 'friend id' :当我运行此 SQL 语句时,我得到 1 个(表中存在的 3 个)随机“朋友 ID”:
SELECT t1.sender_id AS Connections FROM
(SELECT DISTINCT sender_id
FROM connection
WHERE receiver_id = 'my_id'
AND status = 'Approved') t1
UNION ALL
SELECT t2.receiver_id FROM
(SELECT DISTINCT receiver_id
FROM connection
WHERE sender_id = 'my_id'
AND status = 'Approved') t2
ORDER BY RAND() LIMIT 1;
One random id
is returned which is what I want.返回一个随机
id
,这正是我想要的。
BUT when I wrap the previous SQL statement within another SQL statement to get the friend's name
and id
(from the id
in sub-query) the results come back randomly as either empty or 1 friend or 2 friends or all 3 friends :但是,当我将前一个 SQL 语句包装在另一个 SQL 语句中以获取朋友的
name
和id
(来自子查询中的id
)时,结果随机返回为空或 1 个朋友或 2 个朋友或所有 3 个朋友:
SELECT id, name FROM profile
WHERE id = (
SELECT t1.sender_id AS Connections FROM
(SELECT DISTINCT sender_id
FROM connection
WHERE receiver_id = 'my_id'
AND status = 'Approved') t1
UNION ALL
SELECT t2.receiver_id FROM
(SELECT DISTINCT receiver_id
FROM connection
WHERE sender_id = 'my_id'
AND status = 'Approved') t2
ORDER BY RAND() LIMIT 1);
I want it to emit the same behaviour as the first code snippet.我希望它发出与第一个代码片段相同的行为。
The problem is that the subquery is being re-executed for every row being tested in profile
.问题是正在为
profile
中测试的每一行重新执行子查询。 Each time it returns a different random ID;每次返回不同的随机ID; if that ID happens to match the current row of
profile
, the row is returned.如果该 ID 恰好与
profile
的当前行匹配,则返回该行。
Instead of using WHERE id =
, use a JOIN
.不要使用
WHERE id =
,而是使用JOIN
。 This will just run the subquery once.这将只运行一次子查询。
SELECT p.id, p.name
FROM profile AS p
JOIN (
SELECT t1.sender_id AS Connections FROM
(SELECT DISTINCT sender_id
FROM connection
WHERE receiver_id = 'my_id'
AND status = 'Approved') t1
UNION ALL
SELECT t2.receiver_id FROM
(SELECT DISTINCT receiver_id
FROM connection
WHERE sender_id = 'my_id'
AND status = 'Approved') t2
ORDER BY RAND() LIMIT 1) AS r
ON p.id = r.Connections
Are you really asking for all the sender_ids and one receiver_id?你真的要求所有的sender_ids和一个receiver_id吗?
It feels like you have an extra layer of SELECTs
.感觉就像你有一层额外的
SELECTs
。
When in doubt, add extra parentheses:如有疑问,请添加额外的括号:
( SELECT ... )
UNION ALL
( SELECT ... ORDER BY ...) -- this ORDER BY applies only to the select
ORDER BY ... -- This applies to the result of the UNION, not the second select
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.