Знайдіть ідентифікатори зі списку, які не існують у таблиці


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.