Question

J'ai deux tables qui sont jointes.

A a beaucoup de B

Normalement, vous feriez:

select * from a,b where b.a_id = a.id

Pour obtenir tous les enregistrements d'un a qui a un enregistrement dans b.

Comment puis-je obtenir uniquement les enregistrements dans a qui n'a rien dans b?

Était-ce utile?

La solution

select * from a where id not in (select a_id from b)

Ou, comme le disent d'autres personnes sur ce fil:

select a.* from a
left outer join b on a.id = b.a_id
where b.a_id is null

Autres conseils

select * from a
left outer join b on a.id = b.a_id
where b.a_id is null

Une autre approche:

select * from a where not exists (select * from b where b.a_id = a.id)

Le " existe " Cette approche est utile s’il existe une autre option "Où". clause que vous devez attacher à la requête interne.

SELECT id FROM a
EXCEPT
SELECT a_id FROM b;

Sélectionnez * d'un ID où ne figure pas (sélectionnez a_id parmi b)

Vous obtiendrez probablement de bien meilleures performances (que d'utiliser "pas dans") si vous utilisez une jointure externe:

select * from a left outer join b on a.id = b.a_id where b.a_id is null;

Cela vous protégera des valeurs NULL dans la clause IN, ce qui peut provoquer un comportement inattendu.

sélectionnez * parmi un identifiant où ne figure pas (sélectionnez [un identifiant] parmi b où [un identifiant] n'est pas null )

Dans le cas d’une jointure, c’est assez rapide, mais lorsque nous supprimons des enregistrements de la base de données contenant environ 50 millions d’enregistrements et 4 jointures et plus en raison de clés étrangères, le processus prend quelques minutes. Beaucoup plus rapide à utiliser WHERE NOT IN, comme ceci:

select a.* from a
where a.id NOT IN(SELECT DISTINCT a_id FROM b where a_id IS NOT NULL)
//And for more joins
AND a.id NOT IN(SELECT DISTINCT a_id FROM c where a_id IS NOT NULL)

Je peux également recommander cette approche pour la suppression si nous n’avons pas configuré la suppression en cascade. Cette requête ne prend que quelques secondes.

La première approche est

select a.* from a where a.id  not in (select b.ida from b)

la deuxième approche est

select a.*
  from a left outer join b on a.id = b.ida
  where b.ida is null

La première approche est très chère. La deuxième approche est meilleure.

Avec PostgreSql 9.4, j’ai exécuté la requête "explique" " fonction et la première requête en tant que coût de coût = 0.00..1982043603.32 . Au lieu de cela, la requête de jointure a un coût de cost = 45946.77..45946.78

Par exemple, je recherche tous les produits incompatibles avec aucun véhicule. J'ai 100 000 produits et plus de 1 million de compatibilités.

select count(*) from product a left outer join compatible c on a.id=c.idprod where c.idprod is null

La requête de jointure a pris environ 5 secondes, mais la version de la sous-requête n’a jamais été terminée après 3 minutes.

Une autre façon de l'écrire

select a.*
from a 
left outer join b
on a.id = b.id
where b.id is null

Aïe, battue par Nathan:)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top