【发布时间】:2014-07-09 05:53:47
【问题描述】:
我正在尝试简化我的查询,使其只包含一次会话 ID (SID)。
Users表的抽象结构是:
+----+------+----------+
| ID | Name | Username |
+----+------+----------+
Friends 表具有如下抽象结构:
+----+-----------------+----------+--------+---------+
| ID | UserID | FriendID | Hidden | Deleted |
| | (Foreign key | | | |
| | of ID in Users) | | | |
+----+-----------------+----------+--------+---------+
Sessions表的抽象结构:
+----+-----------------+-----+
| 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
【问题讨论】:
-
如果您可以缩进您的请求,它将更具可读性。
-
尝试使用poorsql.com
-
@AnthonyRaymond 我已经编辑了我的代码
-
你能发布一个带有一些数据的 sqlfiddle 供我们使用吗?还有你想要的输出是什么?
-
@JohnRuddell 我已经为问题添加了一个 sql fiddle 链接
标签: mysql sql join distinct union