Има основно 4 техники за тази задача, всички те са стандартен SQL.
NOT EXISTS
Често най-бърз в 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
);
Също така имайте предвид:
- Какво е по-лесно за четене в EXISTS подзаявки?
LEFT JOIN / IS NULL
Понякога това е най-бързо. Често най-кратък. Често води до същия план за заявка като 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
Къс. Не е толкова лесно интегриран в по-сложни заявки.
SELECT ip
FROM login_log
EXCEPT ALL -- "ALL" keeps duplicates and makes it faster
SELECT ip
FROM ip_location;
Имайте предвид, че (по документация):
дубликатите се елиминират, освен ако
EXCEPT ALL
се използва.
Обикновено ще искате ALL
ключова дума. Ако не ви пука, все пак го използвайте, защото прави заявката по-бърза .
NOT IN
Само добро без NULL
стойности или ако знаете да обработвате NULL
правилно. Аз бине използвайте го за тази цел. Освен това производителността може да се влоши при по-големи маси.
SELECT ip
FROM login_log
WHERE ip NOT IN (
SELECT DISTINCT ip -- DISTINCT is optional
FROM ip_location
);
NOT IN
носи "капан" за NULL
стойности от двете страни:
- Намерете записи, където присъединяването не съществува
Подобен въпрос за dba.SE, насочен към MySQL:
- Изберете редове, където стойността на втората колона не присъства в първата колона