sql >> Databasteknik >  >> RDS >> PostgreSQL

Välj rader som inte finns i andra tabeller

Det finns i princip fyra tekniker för denna uppgift, alla standard SQL.

NOT EXISTS

Ofta snabbast i Postgres.

SELECT ip 
FROM   login_log l 
WHERE  NOT EXISTS (
   SELECT  -- SELECT list mostly irrelevant; can just be empty in Postgres
   FROM   ip_location
   WHERE  ip = l.ip
   );

Tänk också på:

  • Vad är lättare att läsa i EXISTS-underfrågor?

LEFT JOIN / IS NULL

Ibland är detta snabbast. Ofta kortast. Resulterar ofta i samma frågeplan som NOT EXISTS .

SELECT l.ip 
FROM   login_log l 
LEFT   JOIN ip_location i USING (ip)  -- short for: ON i.ip = l.ip
WHERE  i.ip IS NULL;

EXCEPT

Kort. Inte lika lätt att integrera i mer komplexa frågor.

SELECT ip 
FROM   login_log

EXCEPT ALL  -- "ALL" keeps duplicates and makes it faster
SELECT ip
FROM   ip_location;

Observera att (per dokumentation):

dubbletter elimineras om inte EXCEPT ALL används.

Vanligtvis vill du ha ALL nyckelord. Om du inte bryr dig, använd det fortfarande eftersom det gör frågan snabbare .

NOT IN

Bara bra utan NULL värden eller om du vet att hantera NULL ordentligt. Jag skulle inte använda den för detta ändamål. Dessutom kan prestandan försämras med större bord.

SELECT ip 
FROM   login_log
WHERE  ip NOT IN (
   SELECT DISTINCT ip  -- DISTINCT is optional
   FROM   ip_location
   );

NOT IN har en "fälla" för NULL värden på båda sidor:

  • Hitta poster där anslutning inte finns

Liknande fråga på dba.SE riktad mot MySQL:

  • Välj rader där värdet för den andra kolumnen inte finns i den första kolumnen


  1. Förhindrar JDBC-specifikationen '?' från att användas som operator (utanför citattecken)?

  2. Installera Mtop (MySQL Database Server Monitoring) i RHEL/CentOS 6/5/4, Fedora 17-12

  3. Oracle - Hur man skapar en skrivskyddad användare

  4. Skapa en e-postprofil för databas (SSMS)