同一表中记录的MySQL联接类型
这个标题有点别扭,但我会尽我所能解释一下我想要实现的目标 我有一个名为同一表中记录的MySQL联接类型,mysql,sql,join,outer-join,Mysql,Sql,Join,Outer Join,这个标题有点别扭,但我会尽我所能解释一下我想要实现的目标 我有一个名为Users的表和另一个名为Friends的表 用户表的抽象结构为: +----+------+----------+----------+ | ID | Name | Username | Password | +----+------+----------+----------+ Friends表具有如下抽象结构: +----+--------+----------+--------+ | ID | UserID | Fr
Users
的表和另一个名为Friends
的表
用户
表的抽象结构为:
+----+------+----------+----------+
| ID | Name | Username | Password |
+----+------+----------+----------+
Friends
表具有如下抽象结构:
+----+--------+----------+--------+
| ID | UserID | FriendID | Hidden |
+----+--------+----------+--------+
其中,UserID
是发送好友请求的用户的ID,FriendID
是请求的接收者。如果收件人选择隐藏请求,则隐藏列的值为1
我想把这一切压缩成一个查询,到目前为止,我有两个单独的查询使用左连接
或右连接
要查找已发送的请求和当前好友,请执行以下操作:
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
对于收到的好友请求和当前好友:
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
如果我没有解释我需要什么,下面的维恩图可能是一个重要的说明
请注意,为了构造查询,我已选择了所有列,但我只需要结尾处的朋友姓名和ID。在两个查询之间执行
union all
或union 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
在我将
UNION ALL
更改为UNION DISTINCT
以停止重复行(如果两个用户是朋友)之后,这似乎起到了作用。谢谢你的帮助!再多加一点,是否可以提供用户ID,在这个问题中为1,只提供一次?只是我也有一个会话表,所以我将使用一个内部join语句从会话ID中获取用户ID。如果没有,也没关系!你不是已经有了一个案例结构来决定这是否是1吗?你可以这样做,把它从你的子查询添加到你的主查询中,在两个查询中的案例结构之前。我试试看,你能编辑你的答案吗?只是一点提示?如果你不想,我就不接受