sql查询以基于电子邮件获取朋友

时间:2019-01-11 08:30:00

标签: mysql sql join

我有如下示例数据

| users                              |
| user_id | email                    |
|---------|--------------------------|
| 1       | test@example.com |
| 2       | Kanchhi@example.com      |
| 3       | modi@example.com         |
| 4       | andy@example.com         |
| 5       | maya@example.com         |
| 6       | jetli@example.com        |
| 7       | john@example.com         |

| user_relations                                                          |
| user_relation_id | requestor_user_id | receiver_user_id | friend_status |
|------------------|-------------------|------------------|---------------|
| 1                | 2                 | 4                | 1             |
| 2                | 2                 | 6                | 1             |
| 3                | 2                 | 7                | 1             |
| 4                | 5                 | 2                | NULL          |
| 5                | 5                 | 7                | NULL          |
| 6                | 7                 | 2                | NULL          |
| 7                | 7                 | 4                | 1             |
| 8                | 7                 | 5                | 1             |
| 9                | 7                 | 6                | 1             |
| 10               | 4                 | 2                | 1             |
| 11               | 4                 | 3                | 1             |
| 12               | 4                 | 5                | 1             |
| 13               | 4                 | 6                | 1             |
| 14               | 4                 | 7                | 1             |

如果输入的是这两封电子邮件:

Kanchhi@example.com, john@example.com 

然后我的预期输出是这个(顺序无关紧要):

andy@example.com
jetli@example.com 

在上面的示例中,用户ID 2的朋友是用户ID(4、6、7),用户ID 7的朋友是用户ID(2、4、5、6)。因此,用户ID 2和7的共同朋友是 4和6 。我需要共有用户ID的电子邮件地址。

另一个示例输入是:

andy@example.com, john@example.com

那么预期的输出是这样的:

jetli@example.com
Kanchhi@example.com
maya@example.com` 

在上面的示例中,用户ID 4的朋友是(2、6、5、3、2),用户ID 7的朋友是(6、5、2、4)。因此,共同朋友的用户ID为 2、6、5 。我需要在输出中输入这些用户ID的电子邮件地址。

查询1-我尝试过但结果错误

SELECT  u.email 
       FROM user_relations r 
        LEFT JOIN users u   ON r.requestor_user_id = u.user_id
        LEFT JOIN users z   ON r.receiver_user_id = z.user_id
       where u.email in ('Kanchhi@example.com','john@example.com') or 
       z.email in ('Kanchhi@example.com','john@example.com') 
       and r.friend_status = 1 
       group by u.email 
      having count(u.email ) > 1

结果-但不是正确的

| email               |
|---------------------|
| andy@example.com    |
| john@example.com    |
| Kanchhi@example.com |

如何获得?

5 个答案:

答案 0 :(得分:1)

问题的症结在于建立一个用户列表,这些用户是Kanchi和John的朋友,或者是他们的朋友。然后计算两次出现在列表中的用户:

-- SELECT email FROM users WHERE userid IN (
SELECT friendid
FROM (
    SELECT requestor_user_id AS userid, receiver_user_id AS friendid
    FROM user_relations
    WHERE friend_status = 1 AND requestor_user_id IN (
        SELECT user_id
        FROM users
        WHERE email IN ('Kanchhi@example.com','john@example.com')
    )

    UNION ALL

    SELECT receiver_user_id, requestor_user_id
    FROM user_relations
    WHERE friend_status = 1 AND receiver_user_id IN (
        SELECT user_id
        FROM users
        WHERE email IN ('Kanchhi@example.com','john@example.com')
    )
) AS X
GROUP BY friendid
HAVING COUNT(DISTINCT userid) = 2

与用户匹配结果很简单。对于您的样本输入,结果是:

4    Andy     andy@example.com     ashutosh    2019-01-11 13:34:05
6    jetli    jetli@example.com    ashutosh    2019-01-11 13:34:05

答案 1 :(得分:0)

您可以从用户开始,然后加入关系。

然后在接收方和请求方上与用户不同的组。

SELECT 
case when u.user_id = r.receiver_user_id then requestor.email else receiver.email end as friend_email
FROM users u
JOIN user_relations r 
  ON (r.requestor_user_id = u.user_id OR r.receiver_user_id = u.user_id)
 AND r.friend_status = 1 
LEFT JOIN users requestor ON requestor.user_id = r.requestor_user_id
LEFT JOIN users receiver ON receiver.user_id = r.receiver_user_id
WHERE u.email in ('Kanchhi@example.com','john@example.com') 
GROUP BY friend_email
HAVING COUNT(DISTINCT u.user_id) > 1

结果:

friend_email
----------------
andy@example.com 
jetli@example.com 

答案 2 :(得分:0)

您可以使用它并在联接库伦中使用索引来提高性能

SELECT DISTINCT u.email
FROM
(
    SELECT r.receiver_user_id AS id, u.email
    FROM user_relations r 
    INNER JOIN users u
    ON r.requestor_user_id = u.user_id 
    WHERE r.friend_status = 1 AND u.email = 'Kanchhi@example.com'
    UNION ALL
    SELECT r.requestor_user_id AS id, u.email
    FROM user_relations r 
    INNER JOIN users u
    ON r.receiver_user_id = u.user_id 
    WHERE r.friend_status = 1 AND u.email = 'Kanchhi@example.com'
) k
INNER JOIN
(
    SELECT r.receiver_user_id AS id, u.email
    FROM user_relations r 
    INNER JOIN users u
    ON r.requestor_user_id = u.user_id 
    WHERE r.friend_status = 1 AND u.email = 'john@example.com'
    UNION ALL
    SELECT r.requestor_user_id AS id, u.email
    FROM user_relations r 
    INNER JOIN users u
    ON r.receiver_user_id = u.user_id 
    WHERE r.friend_status = 1 AND u.email = 'john@example.com'
) j
ON k.id = j.id
INNER JOIN users u 
ON k.id = u.user_id 
AND u.email NOT IN ('Kanchhi@example.com','john@example.com');

答案 3 :(得分:0)

尝试一下

SELECT usu.email from users usu where usu.user_id in (
select          r.receiver_user_id
from sov.user_relations r 
where r.requestor_user_id in (
    SELECT  u.user_id from users u where u.email in ('Kanchhi@example.com','john@example.com') 
     )
and r.friend_status = 1      
group by r.receiver_user_id
having count(r.receiver_user_id)  > 1
);

答案 4 :(得分:0)

  

您可以创建类似于以下代码的额外功能

BEGIN
DECLARE limitCount INT DEFAULT 0;
DECLARE counter INT DEFAULT 0;
DECLARE res INT DEFAULT 0;
DECLARE temp TEXT;
SET limitCount = 1 + LENGTH(inputList) - LENGTH(REPLACE(inputList, ',',''));
simple_loop:LOOP
SET counter = counter + 1;
SET temp = SUBSTRING_INDEX(SUBSTRING_INDEX(inputList,',',counter),',',-1);
SET res = FIND_IN_SET(temp,targetList);
IF res > 0 THEN LEAVE simple_loop; END IF;
IF counter = limitCount THEN LEAVE simple_loop; END IF;
END LOOP simple_loop;
RETURN res;
END
  

并像这样使用此功能

find_in_set_extra('Kanchhi@example.com, john@example.com','john@example.com') OR WHAT EVER YOUR INPUTS AND OUTPUTS.