2012-03-11 1 views
1

У меня есть три изображения таблицы, image_tags и теги. таблица изображений содержит информацию о изображениях, теги содержат информацию о тегах и image_tags, содержит взаимосвязь между изображениями и тегами, отношения - это много. Я хочу фильтровать изображения на основе нескольких тегов с условием AND (не IN).несколько И на том же соединенном столе coulmnn

Я попытался:

SELECT images.* FROM images 
LEFT JOIN image_tags ON image_tags.image_id = images.id 
LEFT JOIN tags tag_0 ON image_tags.tag_id = tag_0.id 
LEFT JOIN tags tag_1 ON image_tags.tag_id = tag_1.id 
WHERE tag_0.tag = "tagme" 
AND tag_1.tag = "excellent" 
AND images.filesize > 0 
GROUP BY images.id 
ORDER BY images.posted DESC LIMIT 0, 40 

И

SELECT images.* FROM images 
LEFT JOIN image_tags ON image_tags.image_id = images.id 
LEFT JOIN tags ON image_tags.tag_id = tags.id 
WHERE tags.tag = "tagme" 
AND tags.tag = "excellent" 
AND images.filesize > 0 
GROUP BY images.id 
ORDER BY images.posted DESC LIMIT 0, 40 

Но ничего не получалось, что всегда возвращается нулевой результат, хотя они существуют.

ответ

0

Ни одна из ваших попыток не является достаточно правильной, хотя первая из них ближе к правильной. Чтобы отфильтровать теги так, как вы пытаетесь их отфильтровать, вам нужно присоединиться к image_tags дважды и присоединиться к обоим экземплярам tags, чтобы разделить экземпляры image_tags. И кажется, что вы хотите делать внутренние объединения, а не внешние соединения. Здесь:

SELECT i.* 
FROM images i 
    INNER JOIN image_tags it0 ON it0.image_id = i.id 
    INNER JOIN tags t0 ON t0.id = it0.tag_id 
    INNER JOIN image_tags it1 ON it1.image_id = i.id 
    INNER JOIN tags t1 ON t1.id = it1.tag_id 
WHERE i.filesize > 0 
    AND t0.tag = 'tagme' 
    AND t1.tag = 'excellent' 
ORDER BY i.posted DESC 
LIMIT 0, 40 

Есть и другой способ, которым вы могли бы сделать то же самое. Попробуйте следующее:

SELECT i.* 
FROM images i 
    INNER JOIN image_tags it ON it.image_id = i.id 
    INNER JOIN tags t ON t.id = it.tag_id 
WHERE i.filesize > 0 
    AND t.tag IN ('tagme', 'excellent') 
GROUP BY i.id 
HAVING COUNT(DISTINCT i.tag) = 2 
ORDER BY i.posted DESC 
LIMIT 0, 40 

В t.tag IN ('tagme', 'excellent') условие ограничивает допустимые теги для указанного списка и HAVING COUNT(DISTINCT i.tag) = 2 убеждается изображение имеет все из них.

+0

спасибо .. ты рок-звезда ... – Hirak

1

Ваш первый запрос, даже если он использует LEFT присоединиться, требует хитов в tags на обоих «Тагме» и «отлично», потому что условие в выражении WHERE. Переместить условие в предложении ON, как это:

SELECT images.* FROM images 
LEFT JOIN image_tags ON image_tags.image_id = images.id 
LEFT JOIN tags tag_0 ON image_tags.tag_id = tag_0.id AND tag_0.tag = 'tagme' 
LEFT JOIN tags tag_1 ON image_tags.tag_id = tag_1.id AND tag_1.tag = 'excellent' 
WHERE images.filesize > 0 
GROUP BY images.id 
ORDER BY images.posted DESC LIMIT 0, 40 


Ваш второй запрос далеко - он имеет невыполнимое условие:

WHERE tags.tag = "tagme" 
AND tags.tag = "excellent" 

tags.tag не может быть как «Тагме» и "отлично".

+0

Спасибо за быстрый ответ, но это возвращает весь результат без фильтра. Есть идеи? – Hirak

Смежные вопросы