2014-08-28 4 views
0

J'ai une table comme ceci:
Personne Tableau:Sql subselect par clé étrangère

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  

Maintenant que l'utilisateur veut avoir toutes les adresses où thomas 50 ET lisa 20 les deux doivent être. Je veux retourner seulement FK 1.

Ma solution est le (exemple de code) suivant:

select fk 
from person 
where name = thomas and age = 50 
and fk in 
    (select fk from person where name = lisa and age = 20) 

Cela fonctionne, mais donne une meilleure solution que subselect?

Répondre

2

La vôtre fonctionnera, mais un FK est généralement un PK dans une autre table. Peut-être que vous pouvez commencer à partir de cette table?

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) 

Vous pouvez également compter les noms correspondants. Cela facilitera l'ajout de noms, bien que cela puisse être plus lent.

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) 
    ) 

En outre, une jointure interne fonctionnera, aussi longtemps que la combinaison du nom, l'âge et fk est unique, sinon vous obtiendrez des résultats doubles:

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 

Je ne sais pas si ceux-ci surpasseront votre propre requête, mais je pense que les deux sont sémantiquement plus corrects, si vous voulez, et possiblement plus faciles à comprendre et plus faciles à développer.

+0

Peut-être qu'il me manque quelque chose, mais je ne comprends pas d'où vient l'adresse d'une table dans votre solution. – Twelfth

+0

C'est une supposition qu'il y a une autre table, puisque le champ est un FK. Un FK est une clé d'une autre table, donc .. :) S'il n'y a pas de telle table, alors votre auto-jointure est une solution parfaite (c'est une bonne solution quand même, +1), mais dans ce cas, le terme 'FK' serait très déroutant. :) – GolezTrol

+0

AH oui, je vois ce que vous allez faire maintenant ... commencer à la table primaire et rejoindre le FK. C'est une idée plus propre. Heh, 3 alternatives est toujours seulement +1 pas +3;) – Twelfth

2

Auto-jointure? Je ne sais pas si cela sortira de la préforme, mais cela devrait se faire correctement.