PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

SQL:Wählen Sie Datensätze aus, bei denen ALLE verbundenen Datensätze eine Bedingung erfüllen

Unter der Annahme, dass keine Korrelation erforderlich ist, verwenden Sie:

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

Wenn Sie eine Korrelation benötigen:

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

Erklärung

Der EXISTS wertet auf einem booleschen Wert basierend auf der ersten Übereinstimmung aus - das macht es schneller als beispielsweise mit IN und - anders als mit einem JOIN - wird keine Zeilen duplizieren. Der SELECT-Teil spielt keine Rolle – Sie können ihn ändern in EXISTS SELECT 1/0 ... und die Abfrage funktioniert immer noch, obwohl es einen offensichtlichen Fehler bei der Division durch Null gibt.

Die Unterabfrage innerhalb des EXISTS verwendet die Aggregatfunktion MIN, um den kleinsten B.some_val zu erhalten - wenn dieser Wert größer als der a.val-Wert ist, ist a.val kleiner als alle b-Werte. Die einzige Notwendigkeit für ein WHERE -Klausel dient der Korrelation - Aggregatfunktionen können nur im HAVING verwendet werden Klausel.