我试图简化我的查询,以便它只包含会话ID(SID)一次。MySQL删除子查询中的重复子句
用户表的抽象结构是:
+----+------+----------+
| ID | Name | Username |
+----+------+----------+
友表具有一个抽象的结构,如:
+----+-----------------+----------+--------+---------+
| ID | UserID | FriendID | Hidden | Deleted |
| | (Foreign key | | | |
| | of ID in Users) | | | |
+----+-----------------+----------+--------+---------+
会话表的抽象结构:
+----+-----------------+-----+
| ID | UserID | SID |
| | (Foreign key | |
| | of ID in Users) | |
+----+-----------------+-----+
我有以下查询,它已根据前一个查询的答案进行了修改我的。正如你所看到的,会话ID(SID)重复了4次,是否有可能将查询作为一个整体进行压缩,以便SID只需要一次?
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 A.UserID
FROM Friends A
INNER JOIN Sessions S ON A.FriendID = S.UserID
WHERE S.SID = "1234"
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 A.FriendID
FROM Friends A
INNER JOIN Sessions S ON A.UserID = S.UserID
WHERE S.SID = "1234"
AND Deleted = 'No'
)
) D ON C.ID = D.ID
UNION
DISTINCT
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 A.UserID
FROM Friends A
INNER JOIN Sessions S ON A.FriendID = S.UserID
WHERE S.SID = "1234"
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 A.FriendID
FROM Friends A
INNER JOIN Sessions S ON A.UserID = S.UserID
WHERE S.SID = "1234"
AND Deleted = 'No'
)
) D ON C.ID = D.ID
解释系统的基本方式是,如果两个用户是朋友,再有就是在数据库中两个记录。一个从第一个用户到第二个,另一个从第二个用户到第一个。
如果存在从当前用户到另一个用户的记录,并且如果有从一个用户到当前用户的记录已收到好友请求,则发送好友请求。
这里是它如何工作的范恩图:
SQL小提琴 - http://sqlfiddle.com/#!2/c5587/1
这将是更具可读性,如果你能缩进你的申请。 –
尝试使用http://poorsql.com/ – aldux
@AnthonyRaymond我已经编辑了我的代码 –