2010-04-03 11 views
12

J'ai une simple relation un-à-plusieurs. Je voudrais sélectionner des lignes du parent seulement lorsqu'elles ont au moins un enfant. Donc, s'il n'y a pas d'enfants, la ligne parente n'est pas retournée dans le jeu de résultats.Comment sélectionner la ligne parente seulement si elle a au moins un enfant?

Par exemple.

Parent: 
+--+---------+ 
|id| text | 
+--+---------+ 
| 1| Blah | 
| 2| Blah2 | 
| 3| Blah3 | 
+--+---------+ 

Children 
+--+------+-------+ 
|id|parent| other | 
+--+------+-------+ 
| 1| 1 | blah | 
| 2| 1 | blah2 | 
| 3| 2 | blah3 | 
+--+------+-------+ 

Je veux que les résultats soient:

+----+------+ 
|p.id|p.text| 
+----+------+ 
| 1 | Blah | 
| 2 | Blah2| 
+----+------+ 

Répondre

15

Vous pouvez le faire en utilisant un EXISTS, comme ceci:

SELECT * 
FROM Parent p 
WHERE EXISTS (SELECT 1 
       FROM Chilren c 
       WHERE c.Parent = p.id) 

ou en utilisant un IN comme ceci:

SELECT * 
FROM Parent p 
WHERE p.id IN (SELECT c.Parent 
       FROM Chilren c) 
+2

Je ne l'ai pas testé mais je devine que c'est plus lent que d'une jointure. – Hogan

+3

@Hogan - Le existe l'approche la plus rapide. L'optimiseur fera le même plan d'exécution pour une jointure externe vérifiée nulle ... qui sera ** comme ** rapide, mais l'existant n'est jamais plus lent. –

+0

Neat. Merci @Nick. Cela est vrai pour mysql, ms sql et oracle? – Hogan

1
SELECT p.* 
FROM Parent p 
WHERE EXISTS (SELECT 'X' FROM Children c WHERE c.parent = p.id); 
2
Select p.id, p.text 
from Parent p 
inner join Children c on p.id = c.parent 
group by p.id, p.text 
12

Un inner join retourne uniquement les lignes qui correspondent aux deux tables:

select distinct p.* 
from Parent p 
inner join Children c on c.parent = p.id 
+1

Ceci est, à mon avis, le moyen le plus simple d'accomplir ceci et devrait être la réponse acceptée. – adriandz