在MySQL中选择两个查询与单个映射表的交集

时间:2012-06-15 00:33:42

标签: mysql join inner-join intersection intersect

我确信这很容易,但请帮助我,我无法弄清楚为什么我无法返回正确的结果。

非常标准的设置,我有一个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'

正确返回所有标记为“red”的产品familyid。同样:

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'

正确地返回映射到它们的标签“modern contemporary”的产品familyid。问题是,我如何返回仅列有标签的产品系列列表?

我正在尝试这个,它返回空:

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 个答案:

答案 0 :(得分: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