如何将一个表中的多个条目连接到MySQL中的单个关系状态?

时间:2018-03-01 09:55:30

标签: mysql

我有一个表Follow,它只保存UserID跟随TargetID的记录。

如果要求用户A:

  • 如果A或B都没有相互关注,则无关的状态为0,并且不会包含在结果中。
  • 如果用户A跟随B但反之亦然,则B的状态为1 跟随
  • 如果用户B跟随A但反之亦然,则B具有 成为关注者的状态2
  • 如果A跟随B,则B跟随 A,B的状态为3,是朋友

如何在单个MySQL查询中获取给定用户及其状态0以上所有关系的关系状态?

示例:

Users:
+----+-------+
| id | Name  |
+----+-------+
|  1 | Bob   | 
|  2 | Steve |
|  3 | Scott | 
|  4 | Mary  | 
+----+-------+

Follow:
+----+--------+----------+
| id | UserID | TargetID |
+----+--------+----------+
|  1 |      1 |        2 |
|  2 |      1 |        3 |
|  3 |      2 |        1 |
|  4 |      4 |        1 |
+----+--------+----------+

Expected result for user 1:
+----------+--------+-------+
| TargetID | Status | Name  |
+----------+--------+-------+
|        2 |      3 | Steve | (friend)
|        3 |      1 | Scott | (following)
|        4 |      2 |  Mary | (follower)
+----------+--------+-------+

2 个答案:

答案 0 :(得分:2)

您可以使用如下所示的子查询:

-- FOR USER 1
SELECT A.id TargetID,
 SUM(IFNULL((SELECT 1 C FROM Follow B WHERE B.UserID=1 AND B.TargetID=A.id),0) +
     IFNULL((SELECT 2 C FROM Follow D WHERE A.id=D.UserID AND D.TargetID=1), 0)) Status
     , A.name
FROM (SELECT * FROM Users WHERE ID<>1) A
GROUP BY A.id, A.Name
HAVING Status>0; -- for a compact result

-- NOW GLOBALLY
SELECT A.UserID, A.id TargetID,
 SUM(IFNULL((SELECT 1 C FROM Follow B WHERE B.UserID=A.UserID AND B.TargetID=A.id),0) +
     IFNULL((SELECT 2 C FROM Follow D WHERE A.id=D.UserID AND D.TargetID=A.UserID), 0)) Status
     , A.name
FROM (SELECT E.id UserID, F.* FROM Users E JOIN Users F ON E.id<>F.id) A
GROUP BY A.UserID, A.id, A.Name
HAVING Status>0 -- for a compact result
ORDER BY A.UserID;

请参阅DEMO on SQL Fiddle

答案 1 :(得分:0)

我没有试过这个,但尝试了以下几行:

Select t.targetid as TargetId, 
    IF (
        (select count(id) from follow where
         follow.Userid = f.target.id and follow.target_id = u.id) > 1, 
         -- mean’s the target is following user 1
         (IF (
            (select count(id) from follow where
            follow.Userid = u.id and follow.target_id = f.targetid) > 1, 3, 2)) 
            -- if user1 is following aswell, then its a friend, else its a follower
         , 1) 
         -- else means its a following
as status, 
u.name as Name from follow f  
inner Join users u on u.id = f.targetid
where u.id = 1
  1. 内部联接以选择用户1的关系(如果它不存在,则它们不相关)
  2. 如果有记录,则表示他们是3:
  3. 之一