Выберите строки, которых нет в другой таблице



у меня есть две таблицы postgresql:



table name     column names
----------- ------------------------
login_log ip | etc.
ip_location ip | location | hostname | etc.


Я хочу получить каждый IP-адрес от login_log который не имеет строки в ip_location.

Я пробовал этот запрос, но он выдает синтаксическую ошибку.



SELECT login_log.ip 
FROM login_log
WHERE NOT EXIST (SELECT ip_location.ip
FROM ip_location
WHERE login_log.ip = ip_location.ip)



ERROR: syntax error at or near "SELECT"
LINE 3: WHERE NOT EXIST (SELECT ip_location.ip`



мне также интересно, является ли этот запрос (с настройками, чтобы он работал) наиболее эффективным запросом для этой цели.

667   4  

4 ответов:

есть в основном 4 метода для этой задачи, все они стандартные SQL.

NOT EXISTS

часто, Это самый быстрый в Postgres.

SELECT ip 
FROM   login_log l 
WHERE  NOT EXISTS (
   SELECT -- mostly irrelevant what's here; might just be empty in pg
   FROM   ip_location i
   WHERE  l.ip = i.ip
   );

также считают:

LEFT JOIN / IS NULL

иногда это быстрее всего. Часто кратчайший.

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, to keep duplicate rows and make it faster
SELECT ip
FROM   ip_location;

обратите внимание, что (в документации):

дубликаты исключаются, если это.

как правило, вы хотите ALL ключевое слово. Если вам все равно, все равно используйте его, потому что он делает запрос быстрее.

NOT IN

только хорошо без нулевых значений или если вы знаете, чтобы обрабатывать 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:

A.) Команда не существует, вы пропускаете 'S'.

B.) используйте не вместо

SELECT ip 
  FROM login_log 
  WHERE ip NOT IN (
    SELECT ip
    FROM ip_location
  )
;

SELECT * FROM testcases1 t WHERE NOT EXISTS ( SELECT 1
FROM executions1 i WHERE t.tc_id = i.tc_id and t.pro_id=i.pro_id and pro_id=7 and version_id=5 ) and pro_id=7 ;

здесь testcases1 таблица содержит все данные и executions1 таблица содержит некоторые данные среди testcases1 таблицы. Я получаю только данные, которые не присутствуют в таблице exections1. ( и даже я даю некоторые условия внутри, которые вы также можете дать.) укажите условие, которое не должно быть там в получении данных должно быть в скобках.

это также можно попробовать...

SELECT l.ip, tbl2.ip as ip2, tbl2.hostname
FROM   login_log l 
LEFT   JOIN (SELECT ip_location.ip, ip_location.hostname
             FROM ip_location
             WHERE ip_location.ip is null)tbl2

Comments

    Ничего не найдено.