每个外键sql subselect

时间:2014-08-28 17:00:07

标签: sql oracle subquery

我有这样一张桌子:
人员表:

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给它一个更好的解决方案?

2 个答案:

答案 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

不确定是否会预成型,但它应该做得不错。