Có rất nhiều cách để đạt được những gì bạn đang yêu cầu. Có lẽ cách đơn giản nhất là sử dụng cách tiếp cận hoàn toàn theo định hướng:
select election_id from elections
minus -- except is used instead of minus by some vendors
select election_id from votes where user_id = ?
Từ bộ bầu cử, chúng tôi loại bỏ những nơi mà người dùng đã bỏ phiếu. Kết quả có thể được tham gia với các cuộc bầu cử để có được danh hiệu của các cuộc bầu cử. Mặc dù bạn chưa gắn thẻ câu hỏi của mình, vẫn có lý do để tin rằng bạn đang sử dụng MySQL và MINUS hoặc EXCEPT không được hỗ trợ ở đó.
Một biến thể khác là sử dụng NOT EXISTS
vị ngữ:
select election_id, title
from elections e
where not exists (
select 1
from votes v
where e.election_id = v.election_id
and v.user_id = ?
);
Tức là cuộc bầu cử nơi nó không tồn tại một cuộc bỏ phiếu từ người dùng. CácNOT IN
ngữ có thể được sử dụng theo cách tương tự. Vì có thể có null liên quan, điều đáng chú ý là ngữ nghĩa khác nhau giữa IN và EXISTS.
Cuối cùng, bạn có thể sử dụng một tham gia bên ngoài
select election_id, title
from elections e
left join votes v
on e.election_id = v.election_id
and v.user_id = ?
where v.user_id is null;
Nếu không có hàng nào khớp với vị từ ON, thì tất cả các cột từ phiếu bầu sẽ được thay thế bằng null trong kết quả. Do đó, chúng tôi có thể kiểm tra xem có bất kỳ cột nào từ phiếu bầu là null trong mệnh đề WHERE không. Vì cả hai cột trong phiếu bầu có thể là null nên bạn cần cẩn thận.
Tốt nhất, bạn nên sửa các bảng của mình để không phải đối phó với các vấn đề gây ra bởi null:
CREATE TABLE elections
( election_id int NOT NULL AUTO_INCREMENT PRIMARY KEY
, title varchar(255) not null );
CREATE TABLE votes
( election_id int not null
, user_id int not null
, constraint pk_votes primary key (election_id, user_id)
, constraint fk_elections foreign key (election_id)
references elections (election_id)
);