Tìm ID từ danh sách không tồn tại trong bảng


19

Nói rằng tôi có lược đồ và dữ liệu sau:

create table images(
  id int not null
);

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

Tôi muốn thực hiện một truy vấn như:

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

Nhưng điều này không làm việc. Trường hợp trên sẽ trả về 5, vì nó không tồn tại trong các bản ghi bảng.

Câu trả lời:


23

Bạn có thể sử dụng phép nối ngoài với valuesdanh sách (tương tự câu trả lời của Martin đã đề cập ở trên):

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;

hoặc not existscùng với hàm tạo hàng:

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

Nếu bạn thích, bạn cũng có thể đặt valuesmệnh đề vào CTE để làm cho truy vấn cuối cùng dễ đọc hơn:

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

Một cách để làm điều đó là sử dụng VALUESđể tạo một biểu thức bảng với các id để kiểm tra và EXCEPTtìm những cái còn thiếu.

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

6

Trong khi sử dụng EXCEPTnhư @Martin đã cung cấp , hãy nhớ tạo nó EXCEPTALL, trừ khi bạn muốn trả thêm một chút cho việc cố gắng gấp các bản sao.

BTW, một VALUESbiểu thức có thể tự đứng:

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

Nhưng bạn có được tên cột mặc định theo cách này.

Đối với một danh sách dài các giá trị, có thể thuận tiện hơn để cung cấp nó dưới dạng mảng và không cần thiết. Cú pháp ngắn hơn:

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

Có một vài kỹ thuật cơ bản cho nhiệm vụ:


0

Chỉ cần sử dụng một bảng thứ hai và tham gia với họ.

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
Nếu bạn đang thực hiện một lựa chọn đơn giản và bạn đang tạo một bảng chỉ cho việc này thì đó có thể không phải là giải pháp tốt nhất.
Patrick D'appollonio
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.