Пытаясь понять сложное соединение - PullRequest
1 голос
/ 29 декабря 2011

Ниже мой запрос

SELECT cover.id              AS cID,
       cover.title           AS cTitle,
       cover.slug            AS cSlug,
       cover.image           AS cImage,
       cover.timestamp       AS cTimestamp,
       category.name         AS catName,
       category.slug         AS catSlug,
       GROUP_CONCAT(tag.tag) AS tags
FROM   cover
       JOIN category
         ON cover.category_id = category.id
       LEFT OUTER JOIN cover_tag
         ON cover_tag.cover_id = cover.id
       LEFT OUTER JOIN tag
         ON tag.id = cover_tag.tag_id
GROUP  BY cover.title
LIMIT  0, 30  

Это вернет все обложки и все теги для каждой обложки.А что если я захочу вернуть только те строки, в которых есть тег «автомобили», НО все равно вернуть все теги, которые есть на обложке?.

Ответы [ 3 ]

2 голосов
/ 29 декабря 2011

Если я понял, о чем вы спрашиваете,

SELECT cover.id              AS cID,
       cover.title           AS cTitle,
       cover.slug            AS cSlug,
       cover.image           AS cImage,
       cover.timestamp       AS cTimestamp,
       category.name         AS catName,
       category.slug         AS catSlug,
       GROUP_CONCAT(tag.tag) AS tags
FROM   cover
       JOIN category
         ON cover.category_id = category.id
       JOIN cover_tag
         ON cover_tag.cover_id = cover.id
       LEFT OUTER JOIN tag
         ON tag.id = cover_tag.tag_id
       JOIN tag T2
         ON T2.id = cover_tag.tag_id AND T2.tag = 'cars'
GROUP  BY cover.title
LIMIT  0, 30  

Последнее объединение должно гарантировать, что cover_tag имеет тег 'cars'.

РЕДАКТИРОВАТЬ Хм, лучшее объяснение ... Изображение? Говорят, сохранено более 9000 слов. Подходящая структура для обложки с набором тегов "фото, машины, отлично" будет:

                     [cover] ---- [category]
                        |
                        |
                        |
[tag:photos] ----/ [cover_tag] ---- [T2:cars]
[tag:cars]   ---/
[tag:great]  --/

Для обложки с набором тегов "clown, shoes, balloon, kids_love_it" T2 не будет соответствовать, поэтому cover_tag не будет соответствовать, поэтому cover не будет соответствовать.

1 голос
/ 29 декабря 2011

Добавляет ли это работу?

HAVING INSTR(CONCAT(',',GROUP_CONCAT(tag.tag),',') , ',Car,') > 0 
0 голосов
/ 29 декабря 2011

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

У вас уже есть 1-й сет: «все теги для (всех) обложек». Второй набор «Обложки с тегом-значением« cars »» будет таким же, как ваш исходный запрос с добавленным предложением WHERE, с фильтрацией по тегу-значению «cars».

Теперь, чтобы объединить два. Техника подчеркивает:

+ Второй запрос идет в «где существует» (или «не существует», как требуется)

+ Второй запрос фильтрует по заданному значению

+ Первичный ключ от каждого экземпляра «центральной» таблицы является частью этого фильтра

SELECT c1.id AS cID, c1.title AS cTitle, c1.slug AS cSlug, c1.image AS cImage, c1.timestamp AS cTimestamp, cat1.name AS catName, cat1.slug AS catSlug,       GROUP_CONCAT( t1.tag ) AS tags
FROM cover c1
JOIN category cat1 ON c1.category_id = cat1.id
LEFT OUTER JOIN cover_tag ct1 ON ct1.cover_id = c1.id
LEFT OUTER JOIN tag t1 ON t1.id = ct1.tag_id
WHERE
    EXISTS (
        SELECT *    -- what we select is irrelevant. We only care that the row exists
        FROM cover c2
        JOIN category cat2 ON c2.category_id = cat2.id
        LEFT OUTER JOIN cover_tag ct2 ON ct2.cover_id = c2.id
        LEFT OUTER JOIN tag t2 ON t2.id = ct2.tag_id
        WHERE
            t2.value = "cars"
            and c1.id = c2.id
    )
GROUP BY c1.title
LIMIT 0 , 30
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...