2012-06-15 5 views
1

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

Довольно стандартная установка, у меня есть ref_product таблица, таблица ref_tagmap и таблица ref_tag ...

CREATE TABLE `ref_product` (
`id` DOUBLE , 
`name` VARCHAR (765), 
`familyid` DOUBLE); 

INSERT INTO `ref_product` (`id`, `name`, `familyid`) VALUES('264','Old Red Fixture 1','4'); 
INSERT INTO `ref_product` (`id`, `name`, `familyid`) VALUES('30206','Modern Red Fixture 2','405'); 


CREATE TABLE `ref_tag` (
`TagID` DOUBLE , 
`TagName` VARCHAR (150)); 

INSERT INTO `ref_tag` (`TagID`, `TagName`) VALUES('103','Modern Contemporary'); 
INSERT INTO `ref_tag` (`TagID`, `TagName`) VALUES('131','Red'); 

CREATE TABLE `ref_tagmap` (
`MapID` DOUBLE , 
`tagid` DOUBLE , 
`containertype` VARCHAR (45), 
`containerid` DOUBLE); 

INSERT INTO `ref_tagmap` (`MapID`, `tagid`, `containertype`, `containerid`) VALUES('17035','131','PROD','264'); 
INSERT INTO `ref_tagmap` (`MapID`, `tagid`, `containertype`, `containerid`) VALUES('17747','131','PROD','30206'); 
INSERT INTO `ref_tagmap` (`MapID`, `tagid`, `containertype`, `containerid`) VALUES('31959','103','PROD','30206'); 

запрос этих таблиц с помощью:

SELECT DISTINCT ref_product.familyid,ref_tag.tagid 
FROM (ref_tag,ref_product) 
JOIN ref_tagmap AS mt2 ON mt2.containerid=ref_product.id 
AND mt2.containertype='PROD' 
AND mt2.tagid=ref_tag.tagid 
AND ref_tag.tagname='red' 

правильно возвращает все familyids продукта которые имеют тег 'red', сопоставленный с ними. Аналогичным образом:

SELECT DISTINCT ref_product.familyid,ref_tag.tagid 
FROM (ref_tag,ref_product) 
JOIN ref_tagmap AS mt1 ON mt1.containerid=ref_product.id 
AND mt1.containertype='PROD' 
AND mt1.tagid=ref_tag.tagid 
AND LCASE(ref_tag.tagname)='modern contemporary' 

правильно возвращает семейство товаров, у которых есть метка «современный современный», нанесенный на них. ВОПРОС: КАК Я ВОЗВРАЩАЮТ СПИСОК ТОЛЬКО СЕМЕЙСТВ С ПРОДУКТАМИ, КОТОРЫЕ ИМЕЛИ СВОИ ТЕГИ?

Я пытаюсь это, и он возвращает пустой:

SELECT DISTINCT ref_product.familyid,ref_tag.tagid 
FROM (ref_tag,ref_product) 
JOIN ref_tagmap AS mt2 ON mt2.containerid=ref_product.id 
AND mt2.containertype='PROD' 
AND mt2.tagid=ref_tag.tagid 
AND ref_tag.tagname='red' 
JOIN ref_tagmap AS mt1 ON mt1.containerid=ref_product.id 
AND mt1.containertype='PROD' 
AND mt1.tagid=ref_tag.tagid 
AND LCASE(ref_tag.tagname)='modern contemporary' 

я должен считать, что я что-то фундаментальное здесь отсутствует ... чувство плотными. Пожалуйста помоги.

Спасибо!

ответ

1

Типичный способ сделать это - убедиться, что количество отдельных элементов в таблице tag равно количеству тегов, которые вы хотите изолировать.
Пример:

SELECT p.familyid 
FROM ref_product p 
     JOIN ref_tagmap tm ON tm.containerid=p.id 
     AND tm.containertype='PROD' 
     JOIN ref_tag t ON t.tagid = tm.tagid 
     AND t.tagname IN ('red', 
         'modern contemporary') 
GROUP BY p.familyid 
HAVING count(DISTINCT t.tagid) = 2; 

В действии: http://sqlfiddle.com/#!2/f377e/7

+0

Bernie, спасибо за ответ ... но я не уверен, что это поможет. Я пытаюсь изолировать, как структурировать это маленькое предложение ... которое является частью гораздо более крупного запроса с дюжиной или около того условий (и еще нескольких связанных таблиц, и я уже группирую что-то еще.) Итак, я Я пытаюсь понять, есть ли способ строго ограничить результаты, возвращаемые только тем, у которых оба отображаемых тега. Любой другой способ кожи этой кошки? – OldSchool

+0

Я добавлю, что мне действительно не нужно возвращать tag_id или tag_name, просто product.familyid, помеченный всеми переданными тегами. – OldSchool

+0

Добро пожаловать. Обратите внимание, что этот запрос можно использовать в качестве подзапроса во внешнем запросе. Или присоединитесь к нему (некоторые называют эту производную таблицу) или используют его как коррелированный подзапрос (в предложении WHERE внешнего запроса). – bernie