我有如下示例数据
| 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 |
如何获得?
答案 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.