想象一下,你有两张桌子,有一对多的关系。
对于这个例子,我建议有两个表:Person和Homes。 人员表中包含人员姓名,并为其提供身份证明。家庭表,持有一个人的家庭协会。 PID加入“Person.ID”
而且,在这个小小的数据库中,一个人可以没有家,也没有许多家。
我希望我画得正确。
如何编写一个select,它会返回每个每个指定的房屋类型的所有人?
假设这些是家庭表中有效的“类型”:
Cottage,Main,Mansion,Spaceport。
我想在Person表中返回一个拥有spaceport 和一个Cottage的人。
我能想出的最好的是:
SELECT DISTINCT( p.name ) AS name
FROM person p
INNER JOIN homes h ON h.pid = p.id
WHERE 'spaceport' in (
SELECT DISTINCT( type ) AS type
FROM homes
WHERE pid = p.id
)
AND 'cottage' in (
SELECT DISTINCT( type ) AS type
FROM homes
WHERE pid = p.id
)
当我写这篇文章时,它有效,但我很确定必须有更好的方法。
答案 0 :(得分:9)
此处的HAVING子句将保证返回的人员两种类型,而不仅仅是其中一种。
SELECT p.name
FROM person p
INNER JOIN homes h
ON p.id = h.pid
AND h.type IN ('spaceport', 'cottage')
GROUP BY p.name
HAVING COUNT(DISTINCT h.type) = 2
答案 1 :(得分:1)
select * from homes;
home_id person_id type
--
1 1 cottage
2 1 mansion
3 2 cottage
4 3 mansion
5 4 cottage
6 4 cottage
要找到同时包含小屋和大厦的每个人的ID号,按照ID号分组,将输出限制为小屋和大厦,并计算不同的类型。
select person_id
from homes
where type in ('cottage','mansion')
group by person_id
having count(distinct type) = 2;
person_id
--
1
您可以在联接中使用此查询来获取人员表中的所有列。
select person.*
from person
inner join (select person_id
from homes
where type in ('cottage','mansion')
group by person_id
having count(distinct type) = 2) T
on person.person_id = T.person_id;
感谢Joe指出我的count()中的错误。
答案 2 :(得分:0)
不确定这个的性能,但这里有:
SELECT PID FROM (
SELECT PID, COUNT(PID) cnt FROM (
SELECT DISTINCT PID, Type FROM Homes
WHERE Type IN ('Type1', 'Type2', 'Type3')
) a
GROUP BY PID
) b
WHERE b.cnt = 3
您必须动态生成IN
子句以及WHERE b.CNT
子句。