2011-11-07 80 views
2

这是一个这样的基本问题,但由于某种原因,我所有的SQL知识都刚刚退出大楼。三个基本表:MySQl返回与第二个表值匹配和/或的记录

Table A 
id | name 
--------- 
1 | John 
2 | Mike 
3 | Henry 
4 | Cooper 

Table B 
id | tag 
--------- 
1 | chocolate 
2 | ice cream 
3 | cookies 

和联接两个表:

Table C 
id | name_id | tag_id 
--------------------- 
1 | 1 | 2 
2 | 1 | 3 
3 | 2 | 1 
4 | 3 | 2 
5 | 3 | 3 

我想找个谁都喜欢巧克力和饼干的人。以下给我所有喜欢巧克力和饼干的人,但我只想要喜欢两者的人(巧克力和饼干而不是巧克力或饼干)。

SELECT name FROM tablea a JOIN tablec c ON a.id = c.name_id WHERE c.tag_id IN (1,3) 

下显然是行不通的:

SELECT name FROM tablea a JOIN tablec c ON a.id = c.name_id WHERE c.tag_id = 1 AND c.tag_id = 3 GROUP BY name 

,但它本质上我想要的。另外,我想这样做而不涉及JOIN中的tableb,因为我在这里使用它将会有不同的其他表加入,我不想混淆图片。这一定非常简单!

回答

4

一个hackish的方法:

SELECT name, COUNT(c.tag_id) AS cnt 
FROM tablea a 
JOIN tablec c ON a.id = c.name_id 
WHERE c.tag_id IN (1,3) 
GROUP BY name 
HAVING cnt = 2 

计数每个用户多少偏好具有(这将通过where子句限于巧克力或饼干),然后返回仅具有2所偏好的那些用户。

+0

+1尼斯把戏:) – sll

+1

只要'表C'不能有重复的记录(即'(name_id,tag_id)')的唯一约束,这看起来很棒 – Phil

+1

@Phill:我想有些人可以真的喜欢cookies,但至少在mysql中,你也可以有'COUNT(DISTINCT ...)处理这些蠢事。 –

2

最简单和最快的方式是加入tablec两次,一个是巧克力和其他的饼干

select name 
    from tablea a 
inner join tablec chocolates on a.id = chocolates.name_id 
inner join tablec cookies on a.id = cookies.name_id 
where chocolates.tag_id = 1 
    and cookies.tag_id = 3 
+0

@Phil感谢指出重复的行。到'select distinct'。'Group by name'也可以做到这一点 –

+0

我回滚了我的最后一条评论,因为这个查询没有返回重复的行,因此不需要明确的子句 –

相关问题