我有一张这个人知道的人和语言的桌子。对于前
Name Language
John Engl ish
Bill English
John German
Bill Japanese
Li Chinese
我想选择所有懂英语和德语的人。 简单的方法就是这样做:
select name from persons p where
exists (select 1
from persons pp
where pp.name=p.name
and pp.language="English")
AND
exists (select 1 from persons pp
where pp.name=p.name
and pp.language="English")
请求的复杂性是n ^ 2; 但是,如果我需要选择所有懂英语,德语和俄语的人呢?我会有复杂性n ^ 3。等等.. 有没有更快的方法呢?
答案 0 :(得分:1)
你想要那些会说英语and
日语的人的名字;不是英语or
日语的人的名字,对吗?如果是这样,这是一种没有任何连接或子查询的方法:
select name, count(name)
from persons
where language in ('English', 'Japanese')
group by name
having count(name)=2
如果您需要添加更多语言,只需将其他语言添加到where
子句中,并将最后一行中的数字增加到您拥有的语言数。
答案 1 :(得分:0)
试试这个:
select name from persons p where p.language in ('English', 'German', 'Russian');
答案 2 :(得分:0)
尝试这一个选择
Select name from (
Select name, GROUP_CONCAT(DISTINCT language
ORDER BY language ASC SEPARATOR ' ') as gr from persons group by name) as t
WHERE gr = 'English Russian';
但是这个适用于完全匹配。您可以使用INSTR mysql函数以更多语言进行搜索。
但是,我的主要建议是创建另一个结构,因为你有多对多的关系。
答案 3 :(得分:0)
将表格结构修改为:
<强>人强>
person_id | name
----------+------
1 | John
2 | Bill
3 | Li
语言强>
language_id | language
------------+---------
1 | English
2 | German
3 | Japanese
4 | Chinese
<强> people_have_languages 强>
person_id | language_id
----------+------------
1 | 1
2 | 1
1 | 2
2 | 3
3 | 4
现在您将拥有一个规范化的表结构,这里是您的查询:
SELECT
`people`.`name`
FROM
`people`
INNER JOIN `people_have_languages` ON (`people`.`person_id`=`people_have_languages`.`person_id`)
INNER JOIN `languages` ON (`people_have_languages`.`language_id`=`languages`.`language`)
WHERE
`language` IN ('English', 'German', 'Russian')
GROUP BY
`people`.`person_id`