Как слева объединить несколько таблиц в MySQL? - PullRequest
5 голосов
/ 10 января 2011

У меня проблема с объединением трех таблиц в MySQL.

допустим, у нас есть таблица с именем posts, в которой я храню свои записи, у меня есть таблица с именем likes, в которой я храню user_id и post_id, и третья таблица с именем comments, в которой я храню user_id и post_id и текст комментария в нем.

Мне нужен запрос, который выбирает список моих записей с указанием количества лайков и комментариев для каждой записи.

Я использую этот запрос:

SELECT posts.id, count(comments.id) as total_comments, count(likes.id) as total_likes
FROM `posts`
LEFT OUTER JOIN comments ON comments.post_id = posts.id 
LEFT OUTER JOIN likes ON likes.post_id = posts.id
GROUP BY posts.id

но есть проблема с этим запросом, если комментарии для элемента пустые, количество лайков просто в порядке, но, скажем, если в записи есть 2 комментария и 4 лайка, то total_comments и total_likes будут равны "8", что означает что MySQL умножает их. Я в замешательстве и не знаю, что мне делать.

Спасибо заранее.

Ответы [ 2 ]

7 голосов
/ 10 января 2011

Используйте count(distinct comments.id) и count(distinct likes.id), если эти идентификаторы уникальны.

4 голосов
/ 10 января 2011

Ну, это один из способов приблизиться к нему (при условии, что mysql разрешает производные таблицы):

SELECT posts.id, comments.total_comments, likes.total_likes 
FROM `posts` 
LEFT OUTER JOIN (select post_id,  count(id) as total_comments from  comments) comments 
    ON comments.post_id = posts.id  
LEFT OUTER JOIN (select post_id,  count(id) as total_likes from  likes) likes 
    ON likes.post_id = posts.id 

Вы также можете использовать коррелированные подзапросы. Возможно, вы захотите, чтобы в статистике дел учитывались значения 0, если нет соответствующих записей.

Давайте попробуем коррелированный подзапрос:

SELECT posts.id, 
(select count(Id) from comments where post_id = posts.id) as total_comments, 
(select count(Id) from likes where post_id = posts.id) as total_likes 
FROM `posts` 
...