2015-03-12 2 views
2

Итак, у меня есть две таблицы MySQL; один называется users, а другой называется likes.Объединение двух таблиц в MySQL на основе взаимных симпатий

Пользователи Таблица

id   name 
-----  ------ 
1   Mark 
2   John 
3   Paul 
4   Dave 
5   Chris 

Любит стол

liked_by liked match_id 
-----  ------ -------- 
    1   2   1 
    2   1   2 
    1   3   3 
    2   3   4 
    1   5   5 
    5   1   6 

Я смог успешно объединить эти две таблицы следующим образом

SELECT users.id, likes.* 
FROM users 
JOIN likes 
ON users.id = likes.liked 

Но я не уверен, как отформатировать WHERE так, чтобы возвращались следующие строки.

name  liked_by liked  match_id 
------ -------  -------- -------- 
Mark   1   3   3 
John   2   3   4 

Как вы можете видеть, я пытаюсь вернуть строки, где Марк и Джон оба похожи на одного и того же пользователя. В этом случае это пользователь 3, или Пол. Я попытался добавить в запрос следующее предложение, но он явно не работает.

WHERE (likes.liked_by = '1' OR likes.liked_by = '2') 
+1

Я не может понять '' liked_by столбцы ожидаемого результата? Вы можете объяснить бит. –

+0

Извините. Это была опечатка. Я исправил его сейчас – Lance

+0

Из предоставленного вывода, я бы предположил, что две таблицы должны быть объединены на основе loved_by, то есть ON users.id = loved_by.liked –

ответ

2

Найдите понравившиеся (похожие?), Которые имеют несколько строк. В противном случае это просто внутреннее соединение:

select * 
from Likes as l inner join Users as u on u.id = l.liked_by 
where liked in (
    select liked 
    from Likes 
    --where liked_by in (:userid1, :userid2) /* optional: specific pair of users */ 
    --where liked (:userid1, :userid2) /* optional: specific likee */ 
    group by liked 
    having count(*) > 1 
) 

Я слышал много, что in подзапросов не оптимизируют хорошо на MySQL. Поскольку группировка гарантирует взаимно-однозначные отношения, легко преобразовать ее во внутреннее соединение на производном столе/встроенном представлении/вложенном представлении или как вы его называете.

+0

Я пробовал это, и CodeIgniter возвращает ошибку DB, читающую 'У вас есть ошибка в синтаксисе SQL; проверьте руководство, соответствующее версии сервера MySQL, для правильного синтаксиса для использования рядом с .id = l.liked_by WHERE понравилось IN (SELECT понравилось FROM li 'в строке 3' – Lance

+0

Я просто набрал слишком быстро и в основном не использовал слово ' on'. – shawnt00

1

Вам необходимо ПРИСОЕДИНИТЕСЬ к таблице likes с собой, чтобы получить список пар пользователей, которые любят конкретного пользователя. Запрос довольно прямолинейный.

Тестовых данные:

CREATE TABLE users (id INT, name VARCHAR(100)); 
INSERT INTO users(id, name) VALUES (1,'Mark'), (2,'John'), (3,'Paul'), (4,'Dave'), (5,'Chris'); 

-- Note: I assumed that match_id is a primary key 
CREATE TABLE likes (match_id INT PRIMARY KEY AUTO_INCREMENT, liked_by INT, liked INT); 
INSERT INTO likes(liked_by, liked) VALUES (1,2), (2,1), (1,3), (2,3), (1,5), (5,1); 

Фактический запрос:

SELECT CONCAT(user1.name, ' and ', user2.name, ' like ', user3.name) AS `Readable result` 
-- join the likes table with itself where two users like the same user 
FROM likes AS like1 
INNER JOIN likes AS like2 ON like1.liked = like2.liked AND 
          like1.match_id < like2.match_id 
-- join the result with user table three times to obtain names of all users involved 
INNER JOIN users AS user1 ON like1.liked_by = user1.id 
INNER JOIN users AS user2 ON like2.liked_by = user2.id 
INNER JOIN users AS user3 ON like1.liked = user3.id 

Результат:

+--------------------------+ 
| Readable result   | 
+--------------------------+ 
| Mark and John like Paul | 
| John and Chris like Mark | 
+--------------------------+ 
Смежные вопросы