電子メールに基づいて相互の友達を取得するためのSQLクエリ

I created a fiddle with my schema and data here >> SQLフィドル

入力がこの2つのメールの場合

[email protected][email protected]

予想される成果

[email protected][email protected]


概要説明(表のデータによる)

The friendiend of user id 2 is user ids (4,6,7) and friend of user id 7 is user ids(2,4,5,6) so the mutual friend of user id 2 & 7 is (4 and 6 ) << this is my expected output but i need email address of mutual userId(4,6)

SQLフィドル

MySQL 5.6 Schema Setup:

CREATE TABLE  IF NOT EXISTS  `users` (
  `user_id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `username` varchar(15) NOT NULL,
  `email` varchar(100) NOT NULL,
  `password` varchar(200) NOT NULL,
  `create_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP 
) ENGINE=InnoDB DEFAULT CHARSET=latin1;


--
-- Table structure for table `user_relations`
-- 
CREATE TABLE  IF NOT EXISTS  `user_relations` (
  `user_relation_id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `requestor_user_id` int(11) NOT NULL,
  `receiver_user_id` int(11) NOT NULL,
  `friend_status` int(2) DEFAULT NULL COMMENT '1- yes both are friend,  other then this "1" value is not friend',
  `follow_status` int(2) DEFAULT NULL COMMENT '1- yes requestor is following(subscribed to update)  receiver,  other then this "1" value is following',
  `follow_back_status` int(2) DEFAULT NULL COMMENT '1- yes both following each other i.e subscribed to update)  receiver,  other then this "1" value is following',
  `created_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `updated_date` datetime NULL DEFAULT NULL COMMENT 'can be null also initially, it depends upon the requirement', 
   CONSTRAINT `user_relations_ibfk_1` FOREIGN KEY (`requestor_user_id`) REFERENCES `users` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
    CONSTRAINT `user_relations_ibfk_2` FOREIGN KEY (`receiver_user_id`) REFERENCES `users` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE 

) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='This table contains relation ship with users table';
   INSERT INTO `users` (`user_id`, `username`, `email`, `password`, `create_date`) 
VALUES (1, 'ashutosh', '[email protected]', 'ashutosh', CURRENT_TIMESTAMP);

INSERT INTO `users` (`user_id`, `username`, `email`, `password`, `create_date`) 
VALUES (2, 'Kanchhi', '[email protected]', 'ashutosh', CURRENT_TIMESTAMP); 

INSERT INTO `users` (`user_id`, `username`, `email`, `password`, `create_date`) 
VALUES (3, 'modi', '[email protected]', 'ashutosh', CURRENT_TIMESTAMP); 

INSERT INTO `users` (`user_id`, `username`, `email`, `password`, `create_date`) 
VALUES (4, 'Andy', '[email protected]', 'ashutosh', CURRENT_TIMESTAMP);  

INSERT INTO `users` (`user_id`, `username`, `email`, `password`, `create_date`) 
VALUES (5, 'maya', '[email protected]', 'ashutosh', CURRENT_TIMESTAMP);

INSERT INTO `users` (`user_id`, `username`, `email`, `password`, `create_date`) 
VALUES (6, 'jetli', '[email protected]', 'ashutosh', CURRENT_TIMESTAMP);

INSERT INTO `users` (`user_id`, `username`, `email`, `password`, `create_date`) 
VALUES (7, 'John', '[email protected]', 'ashutosh', CURRENT_TIMESTAMP); 


INSERT INTO `user_relations` (`user_relation_id`, `requestor_user_id`, `receiver_user_id`, `friend_status`,
 `follow_status`, `follow_back_status`, `created_date`, `updated_date`) 
VALUES (NULL, '2', '4', '1', NULL, NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);

INSERT INTO `user_relations` (`user_relation_id`, `requestor_user_id`, `receiver_user_id`, `friend_status`,
 `follow_status`, `follow_back_status`, `created_date`, `updated_date`) 
VALUES (NULL, '2', '6', '1', '1', NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);


INSERT INTO `user_relations` (`user_relation_id`, `requestor_user_id`, `receiver_user_id`, `friend_status`,
 `follow_status`, `follow_back_status`, `created_date`, `updated_date`) 
VALUES (NULL, '2', '7', '1', NULL, NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);





INSERT INTO `user_relations` (`user_relation_id`, `requestor_user_id`, `receiver_user_id`, `friend_status`,
 `follow_status`, `follow_back_status`, `created_date`, `updated_date`) 
VALUES (NULL, '5', '2', NULL, '1', NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);


INSERT INTO `user_relations` (`user_relation_id`, `requestor_user_id`, `receiver_user_id`, `friend_status`,
 `follow_status`, `follow_back_status`, `created_date`, `updated_date`) 
VALUES (NULL, '5', '7', NULL, '1', '1', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);



INSERT INTO `user_relations` (`user_relation_id`, `requestor_user_id`, `receiver_user_id`, `friend_status`,
 `follow_status`, `follow_back_status`, `created_date`, `updated_date`) 
VALUES (NULL, '7', '2', NULL, '1', NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);



INSERT INTO `user_relations` (`user_relation_id`, `requestor_user_id`, `receiver_user_id`, `friend_status`,
 `follow_status`, `follow_back_status`, `created_date`, `updated_date`) 
VALUES (NULL, '7', '4', '1', NULL, NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);


INSERT INTO `user_relations` (`user_relation_id`, `requestor_user_id`, `receiver_user_id`, `friend_status`,
 `follow_status`, `follow_back_status`, `created_date`, `updated_date`) 
VALUES (NULL, '7', '5', '1', NULL, NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);


INSERT INTO `user_relations` (`user_relation_id`, `requestor_user_id`, `receiver_user_id`, `friend_status`,
 `follow_status`, `follow_back_status`, `created_date`, `updated_date`) 
VALUES (NULL, '7', '6', '1', '1', NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);



INSERT INTO `user_relations` (`user_relation_id`, `requestor_user_id`, `receiver_user_id`, `friend_status`,
 `follow_status`, `follow_back_status`, `created_date`, `updated_date`) 
VALUES (NULL, '4', '2', '1', '1', NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);

INSERT INTO `user_relations` (`user_relation_id`, `requestor_user_id`, `receiver_user_id`, `friend_status`,
 `follow_status`, `follow_back_status`, `created_date`, `updated_date`) 
VALUES (NULL, '4', '3', '1', '1', NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);


INSERT INTO `user_relations` (`user_relation_id`, `requestor_user_id`, `receiver_user_id`, `friend_status`,
 `follow_status`, `follow_back_status`, `created_date`, `updated_date`) 
VALUES (NULL, '4', '5', '1', '1', NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);


INSERT INTO `user_relations` (`user_relation_id`, `requestor_user_id`, `receiver_user_id`, `friend_status`,
 `follow_status`, `follow_back_status`, `created_date`, `updated_date`) 
VALUES (NULL, '4', '6', '1', '1', NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);


INSERT INTO `user_relations` (`user_relation_id`, `requestor_user_id`, `receiver_user_id`, `friend_status`,
 `follow_status`, `follow_back_status`, `created_date`, `updated_date`) 
VALUES (NULL, '4', '7', '1', '1', NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);

Query 1- I tried but got wrong result:

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 ('[email protected]','[email protected]') or 
       z.email in ('[email protected]','[email protected]') 
       and r.friend_status = 1 
       group by u.email 
      having count(u.email ) > 1

Results- but not correct:

|               email |
|---------------------|
|    [email protected] |
|    [email protected] |
| [email protected] |

これを入手するには?

2
nl ru de
あなたの例ではなぜジョンは彼自身の前衛なのですか?
追加された 著者 Salman A,
@SalmanA ユーザーID 2の友人はユーザーID(4,6,7)、ユーザーID 7の友人はユーザーID(2,4,5,6)であるため、ユーザーID 2とユーザーID 7の相互の友人は(4と6)<<�これは私の期待する出力ですが、私は相互のuserId(4,6)の電子メールアドレスが必要です。
追加された 著者 Ashutosh Singh,
sqlfiddleは素晴らしいですが、今日は少し疲れているようです。サンプル表データと予想される結果をフォーマットされたテキストとしても追加できませんか?
追加された 著者 jarlh,
ANDはORよりも先にくることを忘れないでください。おそらく where(u.email in( '[email protected]'、 '[email protected]')またはz.email in( '[email protected]'、 '[email protected]) '))and r.friend_status = 1
追加された 著者 jarlh,
@SalmanAこれはOPの予想される出力ではなく、現在のクエリの出力です。予想はOPポストのトップです。
追加された 著者 Pham X. Bach,
@ jarlhが楽しめます。 SQLFiddleは日に日にますます疲れてきています、私はその理由でdbfiddleを好む傾向があります
追加された 著者 Cid,
@AshutoshSinghが以前のコメントをお願いします
追加された 著者 Carlos Gª-muñoz,

4 答え

答えの核心はこれです:

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 ('[email protected]','[email protected]')
    )

    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 ('[email protected]','[email protected]')
    )
) AS X
GROUP BY friendid
HAVING COUNT(DISTINCT userid) = 2

結果をユーザーと一致させるのは簡単です。サンプル入力の結果は次のとおりです。

4    Andy     [email protected]     ashutosh    2019-01-11 13:34:05
6    jetli    [email protected]    ashutosh    2019-01-11 13:34:05
0
追加された

あなたはユーザーから始めて、そして関係に参加することができます。

Then group on the receiver & requestor that are different from the user.

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 u.user_id IN (r.requestor_user_id, r.receiver_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 ('[email protected]','[email protected]') 
group by friend_email
having count(*) > 1

結果:

friend_email
----------------
[email protected] 
[email protected] 
0
追加された

これを使用してパフォーマンスを向上させるためにjoin coulmnでインデックスを使用することができます。

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 = '[email protected]'
    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 = '[email protected]'
) 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 = '[email protected]'
    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 = '[email protected]'
) j
ON k.id = j.id
INNER JOIN users u 
ON k.id = u.user_id 
AND u.email NOT IN ('[email protected]','[email protected]');
0
追加された

要求者のユーザーテーブルに対して電子メールアドレスをチェックし、受信者のユーザーテーブルから結果を選択するだけです。

SELECT z.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 ('[email protected]','[email protected]') 
  AND r.friend_status = 1 
GROUP BY z.email 
HAVING COUNT(u.email ) > 1
0
追加された