PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

SQL :sélectionnez les enregistrements dans lesquels TOUS les enregistrements joints satisfont à une condition

En supposant qu'aucune corrélation n'est nécessaire, utilisez :

SELECT a.*
  FROM A a
 WHERE EXISTS(SELECT NULL
                FROM B b
              HAVING MIN(b.some_val) > a.val)

Si vous avez besoin d'une corrélation :

SELECT a.*
  FROM A a
 WHERE EXISTS(SELECT NULL
                FROM B b
               WHERE b.id = a.id
              HAVING MIN(b.some_val) > a.val)

Explication

Le EXISTS évalue sur un booléen, basé sur la première correspondance - cela le rend plus rapide que d'utiliser IN, et - contrairement à l'utilisation d'un JOIN - ne dupliquera pas les lignes. La partie SELECT n'a pas d'importance - vous pouvez la changer en EXISTS SELECT 1/0 ... et la requête fonctionnera toujours bien qu'il y ait une erreur évidente de division par zéro.

La sous-requête dans EXISTS utilise la fonction d'agrégation MIN pour obtenir le plus petit B.some_val - si cette valeur est supérieure à la valeur a.val, a.val est inférieur à toutes les valeurs b. Le seul besoin d'un WHERE la clause est pour la corrélation - les fonctions d'agrégat ne peuvent être utilisées que dans le HAVING clause.