2013-10-11 35 views
2

statment我有3个表:Mysql的 “where” 和 “和” 多行

users 
+---------+ 
|id | name| 
+---------+ 
|1 | Tom | 
|2 | Adam| 
+---------+ 
skills 
+------------+ 
|id |name | 
+------------+ 
|1 |baking | 
|2 |driving| 
|3 |etc | 
+------------+ 

users_skills 
+-----------------+ 
|user_id |skill_id| 
+-----------------+ 
| 1  | 1 | 
| 1  | 2 | 
| 2  | 1 | 
| 2  | 2 | 
| 2  | 3 | 
+-----------------+ 

所以结果我有两个用户:

  • 汤姆有1和2个技能
  • 亚当哈斯1和2和3技能

我想获得具有完全技能1和2的所有用户,所以我想得到汤姆。如何实现这一目标?

如果我想获得用户的技能1和技能2 - 这不是一个问题,但它是:(

基本上我想加入用户users_skills表,但我得到的是这样的:

+-----------------------+ 
|user_id |name |sill_id| 
+-----------------------+ 
|1  |Tom | 1 | 
|1  |Tom | 2 | 
+-----------------------+ 
etc 

所以我有两行,我不知道如何实现,在这里发言。

最好的问候,

+0

您正在寻找'GROUP BY users.id' – cmorrissey

回答

0

这是解决方案。棘手的部分是这样的事实,不仅要匹配这些技能,而且也不匹配任何它们。

SELECT u.id, u.name, us.skill_id FROM users u 
JOIN users_skills us ON u.id = us.user_id 
WHERE u.id IN (
    SELECT user_id FROM users_skills 
    WHERE user_id NOT IN (
    SELECT user_id FROM users_skills 
    WHERE skill_id NOT IN (1, 2) 
) 
    GROUP BY user_id 
    HAVING COUNT(DISTINCT skill_id) = 2 
) 

小提琴here。注意我还增加了额外的用户和技能来测试所有情况。

总之:你首先摆脱那些有额外不需要的技能,然后你摆脱那些比所需技能少的人。

输出:

| ID | NAME | SKILL_ID | 
|----|------|----------| 
| 1 | Tom |  1 | 
| 1 | Tom |  2 | 
+0

这正是我想要的问题。但是,是否有可能改变这种情况与另一种情况一起工作。我想让所有具有特定技能的用户,例如只有第三个。根据你的例子,我应该得到亚当,卡尔和迈克。对于1,2我应该得到亚当和汤姆。可能吗? – Krystian

+0

只需在'IN'子句中更新所需技能,并更改'HAVING'子句以反映'IN'子句中项目的数量。 –

0

您需要DISTINCT函数( GROUP BY):

SELECT DISTINCT(u.name) 
FROM users AS u 
JOIN users_skills AS us 
ON u.id = us.user_id 
WHERE us.skillID IN (1,2) 
GROUP BY u.id 
+1

不太去上班 - 这将选择'Adam'过,作为实体也有技巧1和2(和3,这是问题)。此外,您不需要在同一个选择子句中同时使用“DISTINCT”和“GROUP BY”。而且,你遇到了一个潜在危险的mySQL'功能',它可以给出微妙的错误结果;在这种情况下它是安全的(给定表格布局),但是大多数其他RDBMSs会为你想要提取的内容抛出语法错误。 –