sql >> Databáze >  >> RDS >> PostgreSQL

Vyberte řádky, které nejsou přítomny v jiné tabulce

Pro tento úkol existují v zásadě 4 techniky, všechny standardní SQL.

NOT EXISTS

Často nejrychlejší v Postgresu.

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
   );

Zvažte také:

  • Co je snazší číst v EXISTS dílčích dotazech?

LEFT JOIN / IS NULL

Někdy je to nejrychlejší. Často nejkratší. Často vede ke stejnému plánu dotazů jako 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

Krátký. Není tak snadné integrovat do složitějších dotazů.

SELECT ip 
FROM   login_log

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

Všimněte si, že (podle dokumentace):

duplikáty jsou eliminovány, pokud EXCEPT ALL se používá.

Obvykle budete chtít ALL klíčové slovo. Pokud je vám to jedno, stále jej používejte, protože dotaz je rychlejší .

NOT IN

Pouze dobré bez NULL hodnoty nebo pokud víte, jak zpracovat NULL správně. Já bych ne použijte jej pro tento účel. U větších stolů se také může výkon zhoršit.

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

NOT IN nese "past" pro NULL hodnoty na obou stranách:

  • Najít záznamy, kde spojení neexistuje

Podobná otázka na dba.SE zaměřená na MySQL:

  • Vyberte řádky, kde hodnota druhého sloupce není přítomna v prvním sloupci


  1. Jak změnit výchozí port MySQL/MariaDB v Linuxu

  2. Přetypování datového typu Postgres

  3. Oracle vybere nejnovější záznam data

  4. Dotaz MySQL vyhledá hodnoty v řetězci odděleném čárkou