2013-02-23 3 views
1

Я делаю блог, в котором есть статья, в которой могут быть теги и комментарии. Я хочу попробовать и получить правильный SQL, чтобы получить один запрос. У меня есть 4 таблицы:MySQL объединяет 3 таблицы и подсчитывает другую

article 
+------------+-----------------+------------+ 
| article_id | title   | photo  | 
+------------+-----------------+------------+ 
|   1 | This is a test | image1.jpg | 
|   2 | Another Article | image2.jpg | 
+------------+-----------------+------------+ 


article_tag 
+------------+--------+ 
| article_id | tag_id | 
+------------+--------+ 
|   1 |  1 | 
|   1 |  2 | 
|   2 |  2 | 
+------------+--------+ 

tags 
+--------+------+ 
| tag_id | name | 
+--------+------+ 
|  1 | tag1 | 
|  2 | tag2 | 
+--------+------+ 

comment 
+------+---------+------------+ 
| name | message | article_id | 
+------+---------+------------+ 
| 1 | hello |   1 | 
| 2 | a  |   2 | 
+------+---------+------------+ 

Я пытаюсь получить это:

+------------+----------------+------------+---------+----------+ 
| article_id | title   | photo  | tag_ids | comments | 
+------------+----------------+------------+---------+----------+ 
|   1 | This is a test | image1.jpg | 1,2  |  1 | 
+------------+----------------+------------+---------+----------+ 

Это то, что я до сих пор:

SELECT a.article_id, a.title, a.photo, a.date, a.description_long, a.author, GROUP_CONCAT(tag_id) as `tag_ids`, COUNT(c.comment_id) as comments 
FROM article as a 
JOIN article_tag as at 
ON a.article_id = at.article_id 
LEFT JOIN comment as c 
ON a.article_id = c.article_id 
WHERE a.article_id = 1 

Но я получаю комментарии, как 2 вместо 1? Спасибо. PS Если кто-нибудь знает способ, чтобы я мог изменить tag_ids от 1,2 до tag1, tag2, который был бы потрясающим :-)

+0

Там нет столбца с именем 'comment_id' в вашем замечании таблицы ... – Terry

+0

Количества отчетливого, он возвращает 2 строки из-за объединения с тегом – jazzytomato

+0

К сожалению забыло включить это в вопросе. Но у меня есть одна – supajason

ответ

0

Это связано с тем, что существует более 1 метки, так что 2 строки генерируются.

Попробуйте использовать COUNT (DISTINCT c.comment_id). Это будет учитывать только отдельные идентификаторы комментариев, поэтому дубликаты не будут учитываться дважды.

Чтобы получить имена тегов, сделайте левое соединение с таблицей. Затем GROUP_CONCAT с столбцом имени вместо столбца tag_id.

Вот что должно быть:

SELECT a.article_id, a.title, a.photo, a.date, a.description_long, a.author, GROUP_CONCAT(d.name) AS `tag_names`, COUNT(DISTINCT c.comment_id) AS comments 
FROM article as a 
JOIN article_tag as at 
ON a.article_id = at.article_id 
LEFT JOIN comment as c 
ON a.article_id = c.article_id 
LEFT JOIN tags d ON at.tag_id = d.tag_id 
WHERE a.article_id = 1 
+0

Btw, если вы хотите иметь эту информацию для нескольких статей за раз, замените предложение WHERE с помощью GROUP BY a.article_id –

+0

Спасибо, что работа. Мне пришлось ОТПРАВИТЬ в GROUP_CONCAT (d.name) Amazing :-) – supajason

1

Теги и комментарии независимы. Итак, если у вас есть три тега и два комментария, вы получите 6 строк в комбинации.

Самый простой способ исправить этот запрос в MySQL, чтобы сделать группу, и использовать различны в избранных:

SELECT a.article_id, a.title, a.photo, a.date, a.description_long, a.author, 
     GROUP_CONCAT(distinct tag_id) as `tag_ids`, COUNT(distinct c.comment_id) as comments 
FROM article a JOIN 
    article_tag as at 
    ON a.article_id = at.article_id LEFT JOIN 
    comment c 
    ON a.article_id = c.article_id 
WHERE a.article_id = 1 
group by a.article_id 

Я хотел бы сказать, однако, что «правильный» способ исправить запрос является для фиксации соединения. При этом используется подзапросов в from:

from . . . 
    (select article_id, group_concat(tag_id) as tags 
     from tags 
     group by article_id 
    ) at 
    . . . 
    (select article_id, count(*) as numComments 
     from comments 
     group by article_id 
    ) c 
    . . . 
Смежные вопросы