在 MySQL 中使用 UNION ALL 的子查询
Subquery using UNION ALL in MySQL
我想我不明白子查询的工作顺序。
当我 运行 这个 SQL 语句时,我得到 1(table 中存在的 3 个)随机 'friend 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;
随机返回一个id
,这就是我想要的。
BUT 当我将前一个 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);
我希望它发出与第一个代码片段相同的行为。
问题是在 profile
中测试的每一行的子查询都是 re-executed。每次returns一个不同的随机ID;如果该 ID 恰好与 profile
的当前行匹配,则返回该行。
不使用 WHERE id =
,而是使用 JOIN
。这只会 运行 一次子查询。
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
您真的要所有 sender_ids 和一个 receiver_id 吗?
感觉多了一层SELECTs
.
如有疑问,请添加额外的括号:
( 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
我想我不明白子查询的工作顺序。
当我 运行 这个 SQL 语句时,我得到 1(table 中存在的 3 个)随机 'friend 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;
随机返回一个id
,这就是我想要的。
BUT 当我将前一个 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);
我希望它发出与第一个代码片段相同的行为。
问题是在 profile
中测试的每一行的子查询都是 re-executed。每次returns一个不同的随机ID;如果该 ID 恰好与 profile
的当前行匹配,则返回该行。
不使用 WHERE id =
,而是使用 JOIN
。这只会 运行 一次子查询。
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
您真的要所有 sender_ids 和一个 receiver_id 吗?
感觉多了一层SELECTs
.
如有疑问,请添加额外的括号:
( 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