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