sql >> Database >  >> RDS >> PostgreSQL

Vind records waar join niet bestaat

Gebruik een EXISTS uitdrukking:

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

Het verschil

... tussen NOT EXISTS() (Ⓔ) en NOT IN() (Ⓘ) is tweeledig:

  1. Prestaties

    Ⓔ is over het algemeen sneller. Het stopt met het verwerken van de subquery zodra de eerste overeenkomst is gevonden. De handleiding:

    De subquery wordt over het algemeen alleen lang genoeg uitgevoerd om te bepalen of ten minste één rij wordt geretourneerd, niet helemaal tot voltooiing.

    Ⓘ kan ook worden geoptimaliseerd door de queryplanner, maar in mindere mate sinds NULL behandeling maakt het complexer.

  2. Juistheid

    Als een van de resulterende waarden in de subquery-expressie NULL . is , het resultaat van Ⓘ is NULL , terwijl de algemene logica zou verwachten dat TRUE - en Ⓔ retourneert TRUE . De handleiding:

    Als alle resultaten per rij ongelijk of null zijn, met ten minste één null, dan is het resultaat van NOT IN is nul.

In wezen, (NOT) EXISTS is in de meeste gevallen de betere keuze.

Voorbeeld

Uw vraag kan er als volgt uitzien:

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

Doe niet doe mee met votes in de basisquery. Dat zou de moeite teniet doen.

Naast NOT EXISTS en NOT IN er zijn extra syntaxisopties met LEFT JOIN / IS NULL en EXCEPT . Zie:

  • Selecteer rijen die niet aanwezig zijn in een andere tabel


  1. Breek grote verwijderingsbewerkingen in stukken

  2. Records dupliceren om gaten tussen datums te vullen

  3. Hoe installeer ik de Python MySQLdb-module met pip?

  4. MySQL &MariaDB Load Balancing met ProxySQL