Найти идентификаторы из списка, которого нет в таблице


19

Скажем, у меня есть следующая схема и данные:

create table images(
  id int not null
);

insert into images values(1), (2), (3), (4), (6), (8);

Я хочу выполнить запрос как:

select id from images where id not exists in(4, 5, 6);

Но это не работает. Приведенный выше случай должен вернуться 5, так как он не существует в записях таблицы.

Ответы:


23

Вы можете использовать внешнее соединение со valuesсписком (аналогично ответу Мартина, упомянутому выше):

select t.id
from (
  values (4),(5),(6) 
) as t(id)
  left join images i on i.id = t.id
where i.id is null;

или not existsвместе с конструктором строки:

select *
from ( 
   values (4),(5),(6)
) as v(id)
where not exists (select *
                  from images i
                  where i.id = v.id);

Если вам нравится, вы также можете поместить valuesпредложение в CTE, чтобы облегчить чтение окончательного запроса:

with v (id) as (
 values (4),(5),(6)
)
select v.id
from v
  left join images i on i.id = v.id
where i.id is null;

10

Один из способов сделать это VALUES- создать табличное выражение с идентификаторами для проверки и EXCEPTнайти недостающие.

SELECT id
FROM (VALUES(4),(5),(6)) V(id)
EXCEPT
SELECT id 
FROM images;

6

При использовании EXCEPTкак @Martin , не забудьте сделать это EXCEPTALL, если вы не хотите платить немного больше за попытку сложить дубликаты.

Кстати, VALUESвыражение может стоять самостоятельно:

VALUES (4),(5),(6)
EXCEPT ALL
SELECT id FROM images;

Но вы получаете имена столбцов по умолчанию таким образом.

Для длинного списка значений может быть удобнее предоставлять его как массив и как гнездо. Более короткий синтаксис:

SELECT * FROM unnest('{4,5,6}'::int[]) id
EXCEPT ALL
SELECT id FROM images;

Есть несколько основных методов для этой задачи:


0

Просто используйте второй стол и присоединитесь к ним.

create table images1(
  id int not null
);

create table images2(
  id int not null
);

insert into images1 values(1), (2), (3), (4), (6), (8);

insert into images2 values (4), (5), (6);

SELECT i2.ID

FROM images2 i2

LEFT JOIN images1 i1
    ON i1.ID = i2.ID

WHERE i1.ID IS NULL

3
Если вы выполняете простой выбор и создаете таблицу только для этого, это может быть не лучшим решением.
Патрик Д'Аполлонио
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.