我有这样一张桌子:
人员表:
Name | Age | FK Adress
Thomas | 50 | 1
Lisa | 20 | 1
Lisa | 20 | 2
Ramon | 31 | 3
Kata | 56 | 4
Thomas | 50 | 5
Robert | 73 | 6
Karl | 78 | 7
Edda | 11 | 8
Yogi | 22 | 9
现在用户希望拥有thomas 50和lisa 20都必须的所有地址。 我想只回到FK 1.
我的解决方案如下(示例代码):
select fk
from person
where name = thomas and age = 50
and fk in
(select fk from person where name = lisa and age = 20)
这有效,但是作为subselect给它一个更好的解决方案?
答案 0 :(得分:2)
你的工作,但FK通常是另一个表中的PK。也许你可以从那张桌子开始?
select pk
from address a
where
exists (
select 'x' from person p
where name = 'lisa' and age = 20 and p.fk = a.pk) and
exists (
select 'x' from person p
where name = 'thomas' and age = 50 and p.fk = a.pk)
或者,您可以计算匹配的名称。这样可以更容易地添加名称,尽管它可能更慢。
select pk
from address a
where
2 = -- the number of names that should match
(select count('x')
from person p
where
p.fk = a.pk and
( (name = 'lisa' and age = 20) or
name = 'thomas' and age = 50)
)
此外,只要name,age和fk的组合是唯一的,内连接就可以使用,否则你会得到双重结果:
select a.pk
from
address a
inner join person l on l.fk = a.pk and l.name = 'lisa' and l.age = 20
inner join person t on t.fk = a.pk and t.name = 'thomas' and l.age = 50
我不知道这些是否会胜过您自己的查询,但我认为两者在语义上更正确,如果您愿意,并且可能更容易理解和更容易扩展。
答案 1 :(得分:2)
自我加入?
Select a.fk
from person a inner join person b on a.fk = b.fk
where a.name = 'thomas' and a.age = 50
and b.name = 'lisa' and b.age = 20
不确定是否会预成型,但它应该做得不错。