проблема с SQL соединением - PullRequest
2 голосов
/ 09 февраля 2011

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

SELECT GROUP_CONCAT(t.tag_name) taglist
FROM posts p
JOIN posts_tags pt ON p.post_id = pt.post_id
JOIN tags t ON t.tag_id = pt.tag_id
WHERE (p.post_private = 0) AND t.tag_name = 'php'
GROUP BY p.post_id

Проблема в том, что запрос выше, выбирает все сообщения, содержащие тег php, но не выбирает другие теги, которые может опубликовать сообщениесодержат.Без части AND t.tag_name = 'php' он выбирает все теги, которые есть в сообщении, но я хочу иметь возможность фильтровать по тегу ...

Есть идеи, как это сделать?Я пробовал много вещей, но не могу понять ...

Пример данных без оператора AND:

|| *taglist* ||
|| php,echo  ||
|| c++, cout ||

Пример данных с оператором AND:

|| *taglist* ||
|| php       ||

Что я хочу:

|| *taglist* ||
|| php,echo  ||

(сообщения, содержащие только тег PHP)

Ответы [ 2 ]

2 голосов
/ 09 февраля 2011
SELECT p.post_id, GROUP_CONCAT(t.tag_name) taglist
    FROM posts p
        /* These 2 joins get the list of all tags */
        INNER JOIN posts_tags pt
            ON p.post_id = pt.post_id
        INNER JOIN tags t
            ON pt.tag_id = t.tag_id
        /* These 2 joins guarantee the 'php' tag is included */
        INNER JOIN posts_tags pt2
            ON p.post_id = pt2.post_id
        INNER JOIN tags t2
            ON pt2.tag_id = t2.tag_id
                AND t2.tag_name = 'php'
    WHERE p.post_private = 0
    GROUP BY p.post_id
1 голос
/ 09 февраля 2011

Я попытаюсь объяснить, почему ваша первая попытка не работает.

Что вы действительно пытаетесь сделать, так это найти все сообщения, которые один из их тегов - 'php'.Но их теги распределены в много строк , поэтому t.tag_name = 'php' не работает, поскольку отфильтровывает все строки, у которых нет тега 'php'.

Когда вы хотите проверитьусловие, которое зависит от многих строк:

вы либо создаете подзапрос (чтобы найти все post_ids, у которых есть тег php)

  p.post_id IN
  ( SELECT pt2.post_id
      FROM post_tags pt2 
        JOIN tags t2
          ON t2.tag_id = pt2.tag_id
      WHERE t2.tag_name = 'php'
  )

, но все же присоединяете эти post_ids ко всем связанным тегам.

SELECT GROUP_CONCAT(t.tag_name) taglist
  FROM posts p
    JOIN posts_tags pt
      ON p.post_id = pt.post_id
    JOIN tags t
      ON t.tag_id = pt.tag_id
  WHERE (p.post_private = 0) 
    AND p.post_id IN
      ( SELECT pt2.post_id
          FROM post_tags pt2 
            JOIN tags t2
              ON t2.tag_id = pt2.tag_id
          WHERE t2.tag_name = 'php'
      )
  GROUP BY p.post_id

Или вы делаете это немного хитрее, как показал Стефанелли с еще 2 JOIN (которые действуют аналогично подзапросу)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...