在 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 语句中以获得朋友的 nameid (来自子查询中的 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