2008-09-24 115 views
2

我有一个多对多的索引表,我想对它做一个包含/排除类型的查询。多对多表查询

fid实际上是一个整数索引,但在这里作为更容易理解的字母。下面是一个示例表:

表t

eid | fid 
----+---- 
1 | A 
1 | B 
1 | C 
2 | B 
2 | C 
3 | A 
3 | C 
4 | A 
4 | B 
5 | B 

这里有我想要一些样本查询。

  1. 什么eids fid B,而不是A? (回答eid 2和5)
  2. 什么eids fid C,而不是A? (回答eid 2)

我似乎无法弄清楚这样做的查询。

我已经尝试了自加入这样的:

select * 
from t as t1 
join t as t2 
where t1.eid=t2.eid 
    and t1.fid!=t2.fid 
    and t1.fid=B and t2.fid!=A 

这是行不通的,因为它仍然会返回行,其中EID = 1,FID = C。

我清楚我想要什么吗?

回答

3

下面是一个查询的示例(2个作品大致相同)

select t1.eid 
    from t t1 
where t1.fid = 'B' 
    and not exists 
     (select 1 
      from t t2 
     where t2.eid = t1.eid 
      and t2.fid = 'A') 
+0

谢谢,在mysql中工作 – Pyrolistical 2008-09-24 19:31:12

7

使用set subtraction

Select eid from t where fid = 'B' 
EXCEPT 
select eid from t where fid = 'A' 
+0

伟大的提示;我从来没有使用EXCEPT语法。 – 2008-09-24 19:25:40

1

您可以使用从T A子选择

选择EID其中FID = 'C' 和EID不是(选择在t EID其中FID = 'A')

0

MySQL 5.0支持存在/不存在的地方,如Nigel和Mike所述。

0

版直联接可能比使用更快的存在:

 
Select t1.eid 
From #test t1 
     left join (
      Select eid 
      From #test t2 
      Where fid = 'A' 
      Group by eid 
     ) t2 on t2.eid = t1.eid 
Where t1.fid = 'B' 
     and t2.eid is null 
0

它应该能够做到这一点,而不使用子查询:

SELECT DISTINCT t1.eid 
FROM table1 AS t1 
    LEFT JOIN table1 AS t2 ON (t1.eid = t2.eid AND t2.fid = 'A') 
WHERE t2.eid IS NULL 
    AND t1.fid = 'B'; 

做你的第二个例子搜索,只需将值“B”更改为“C”。

0

调查MINUS操作员。它的工作方式与UNION类似,只不过它会减去UNION添加的位置。以前的答案与“EXCEPT”一词可能是同一事物的不同关键字。

下面是一个未经测试的答案:

select eid 
from t 
where fid = 'A' 
minus 
select eid 
from t 
where fid = 'B'