Поиск нескольких строк в select с левым соединением - PullRequest
1 голос
/ 16 мая 2011

У меня есть 3 таблицы, products, products_tags и теги. Продукт может быть связан с несколькими тегами через таблицу products_tags.

Но если я хотел бы найти продукт по нескольким тегам, я делаю запрос, подобный этому:

SELECT
    *
FROM
    products
LEFT JOIN
    products_tags
ON
    products_tags.product_id = products.id
LEFT JOIN
    tags
ON
    products_tags.tag_id = tags.id
WHERE
    tags.name = 'test'
AND
    tags.name = 'test2'

Что не работает :(. Если я удаляю теги AND.name = 'test2', это работает. Так что я могу искать только по одному тегу, я объяснил запрос, и он сказал, где невозможно.

Как мне выполнить поиск по нескольким тегам с помощью одного запроса?

Спасибо!

Ответы [ 4 ]

3 голосов
/ 16 мая 2011

Вы пробовали что-то вроде:

WHERE
    (tags.name = 'test'
OR
    tags.name = 'test2')

Или

WHERE
    tags.name in( 'test', 'test2')

Поскольку даже если вы присоединяете один продукт к нескольким тегам, каждая запись тега имеет только одно значение для name.

2 голосов
/ 16 мая 2011

вам нужно присоединиться дважды для теста и теста2:

select products.*
from products
join product_tags as product_tag1 on ...
join tags as tag1 on ...
join product_tags as product_tag2 on ...
join tags as tag2 on ...
where tag1.name = 'test'
and tag2.name = 'test2'

для test или test2, вам нужно одно соединение и предложение in и отличное:

select distinct products.*
from products
join product_tags on ...
join tags as tags on ...
where tags.name IN('test', 'test2')
1 голос
/ 16 мая 2011

Если вы ищете товары, которые имеют ОБА теги "test" и "test2", то вам нужно будет присоединиться к product_tag и таблице тегов по два раза каждый.

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

Пример:

SELECT products.*
FROM products
INNER JOIN products_tags pt1 ON pt1.product_id = products.id
INNER JOIN products_tags pt2 ON pt2.product_id = products.id
INNER JOIN tags t1 ON t1.id = pt1.tag_id
INNER JOIN tags t2 ON t2.id = pt2.tag_id
WHERE t1.name = 'test'
AND t2.name = 'test2'
1 голос
/ 16 мая 2011

Вам нужно будет сгруппировать по и COUNT (*), чтобы ОБА (или сколько их) ВСЕ были найдены.Первый запрос (PreQuery) соединяет таблицу тегов продуктов с тегами и ищет их с соответствующим количеством тегов, чтобы найти ... ТОГДА использует это для присоединения к продуктам для окончательного списка

SELECT STRAIGHT_JOIN
      p.*
   FROM
      ( select pt.product_id
           from products_tags pt
                   join tags on pt.tag_id = tags.id
           where tags.name in ('test1', 'test2' )
           group by pt.product_id
           having count(*) = 2
      ) PreQuery
      join products on PreQuery.Product_ID = Products.ID
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...