同表中记录的 MySQL 连接类型

标签 mysql sql join outer-join

标题有点尴尬,但我会尽力解释我想要完成的事情。

我有一个名为 Users 的表和另一个名为 Friends 的表。

Users 表的抽象结构是:

+----+------+----------+----------+
| ID | Name | Username | Password |
+----+------+----------+----------+

Friends 表的抽象结构如下:

+----+--------+----------+--------+
| ID | UserID | FriendID | Hidden |
+----+--------+----------+--------+

其中 UserID 是发送好友请求的用户的 ID,FriendID 是请求的接收者。如果收件人选择隐藏请求,则隐藏列的值为 1。

我想将这一切压缩为一个查询,到目前为止,我有两个单独的查询,它们使用 LEFT JOINRIGHT JOIN

查找已发送的请求和当前好友:

SELECT 
    *, 
    CASE 
       WHEN C.ID IS Null THEN "Request Sent" 
       ELSE "Friends" 
    END AS Status 
FROM
    (SELECT DISTINCT
         A.ID, A.Name, E.Hidden
     FROM
         Users A 
     INNER JOIN 
         Friends E ON A.ID = E.UserID
     WHERE
         A.ID in (SELECT UserID 
                  FROM Friends 
                  WHERE FriendID = "1" AND Deleted='No')) C
RIGHT JOIN
    (SELECT DISTINCT
         B.ID, B.Name, F.Hidden
     FROM
         Users B 
     INNER JOIN 
         Friends F ON B.ID = F.FriendID
     WHERE
         B.ID in (SELECT FriendID 
                  FROM Friends 
                  WHERE UserID = "1" AND Deleted = 'No')) D ON C.ID = D.ID

关于收到的好友请求和当前好友:

SELECT *, CASE WHEN D.ID IS Null THEN "Wants to be your friend" ELSE "Friends" END AS Status FROM
(SELECT DISTINCT
A.ID, A.Name, E.Hidden
FROM
Users A INNER JOIN Friends E ON A.ID=E.UserID
WHERE
A.ID in (SELECT UserID FROM Friends WHERE FriendID = "1" AND Deleted='No')) C
LEFT JOIN
(SELECT DISTINCT
B.ID, B.Name, F.Hidden
FROM
Users B INNER JOIN Friends F ON B.ID=F.FriendID
WHERE
B.ID in (SELECT FriendID FROM Friends WHERE UserID = "1" AND Deleted='No')) D
ON C.ID=D.ID

如果我没有解释我需要什么,下面的维恩图可能是一个重要的说明性插入。

Venn Diagram

请注意,为了构建查询,我选择了所有列,但最后我只需要 friend 姓名和 ID。

最佳答案

在两个查询之间执行union allunion distinct 这将在一个表中返回所有结果。

SELECT *, D.ID, CASE WHEN D.ID IS Null THEN "Wants to be your friend" ELSE "Friends" END AS Status FROM
(SELECT DISTINCT
A.ID, A.Name, E.Hidden
FROM
Users A INNER JOIN Friends E ON A.ID=E.UserID
WHERE
A.ID in (SELECT UserID FROM Friends WHERE FriendID = "1" AND Deleted='No')) C
LEFT JOIN
(SELECT DISTINCT
B.ID, B.Name, F.Hidden
FROM
Users B INNER JOIN Friends F ON B.ID=F.FriendID
WHERE
B.ID in (SELECT FriendID FROM Friends WHERE UserID = "1" AND Deleted='No')) D
ON C.ID=D.ID
union all
SELECT *, D.ID, CASE WHEN C.ID IS Null THEN "Request Sent" ELSE "Friends" END AS Status FROM
(SELECT DISTINCT
A.ID, A.Name, E.Hidden
FROM
Users A INNER JOIN Friends E ON A.ID=E.UserID
WHERE
A.ID in (SELECT UserID FROM Friends WHERE FriendID = "1" AND Deleted='No')) C
RIGHT JOIN
(SELECT DISTINCT
B.ID, B.Name, F.Hidden
FROM
Users B INNER JOIN Friends F ON B.ID=F.FriendID
WHERE
B.ID in (SELECT FriendID FROM Friends WHERE UserID = "1" AND Deleted='No')) D
ON C.ID=D.ID

关于同表中记录的 MySQL 连接类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23767437/

相关文章:

sql - Oracle:如何向当前日期添加 6 个月

MySQL使用子查询更新,错误1093

mysql - mysql中两个相同表的区别

mysql加入csv字段?

mysql - 如何替换mysql中的多个键

php - 使用 php 和 mysql 处理银行对账

php - 通过 PHP 启动时 SQL 事务不工作

MYSQL 多查询还是单查询——哪个更高效

混合类型的mysql存储过程动态排序

sql - 根据条件连接不同的表