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

Finden Sie Datensätze, bei denen keine Verknüpfung vorhanden ist

Verwenden Sie ein EXISTS Ausdruck:

WHERE NOT EXISTS (
   SELECT FROM votes v  -- SELECT list can be empty
   WHERE  v.some_id = base_table.some_id
   AND    v.user_id = ?
   )

Der Unterschied

... zwischen NOT EXISTS() (Ⓔ) und NOT IN() (Ⓘ) ist zweifach:

  1. Leistung

    Ⓔ ist generell schneller. Es stoppt die Verarbeitung der Unterabfrage, sobald die erste Übereinstimmung gefunden wird. Das Handbuch:

    Die Unterabfrage wird im Allgemeinen nur lange genug ausgeführt, um festzustellen, ob mindestens eine Zeile zurückgegeben wird, nicht bis zum Ende.

    Ⓘ kann auch vom Abfrageplaner optimiert werden, jedoch in geringerem Maße, da NULL Handhabung macht es komplexer.

  2. Korrektheit

    Wenn einer der resultierenden Werte im Unterabfrageausdruck NULL ist , ist das Ergebnis von Ⓘ NULL , während die übliche Logik TRUE erwarten würde - und Ⓔ geben TRUE zurück . Das Handbuch:

    Wenn alle Ergebnisse pro Zeile entweder ungleich oder null sind, mit mindestens einer Null, dann ist das Ergebnis NOT IN ist null.

Im Wesentlichen existiert (NOT) EXISTS ist in den meisten Fällen die bessere Wahl.

Beispiel

Ihre Abfrage kann wie folgt aussehen:

SELECT *
FROM   questions q
WHERE  NOT EXISTS (
    SELECT FROM votes v 
    WHERE  v.question_id = q.id
    AND    v.user_id = ?
    );

nicht Nehmen Sie an votes teil in der Basisabfrage. Das würde den Aufwand zunichte machen.

Außer NOT EXISTS und NOT IN es gibt zusätzliche Syntaxoptionen mit LEFT JOIN / IS NULL und EXCEPT . Siehe:

  • Wählen Sie Zeilen aus, die in keiner anderen Tabelle vorhanden sind