Istnieje wiele sposobów na osiągnięcie tego, o co prosisz. Być może najprostszym sposobem jest zastosowanie podejścia zorientowanego na zestaw:
select election_id from elections
minus -- except is used instead of minus by some vendors
select election_id from votes where user_id = ?
Z zestawu wyborów usuwamy te, w których głosował użytkownik. Wynik można połączyć z wyborami, aby uzyskać tytuł wyborów. Chociaż nie otagowałeś swojego pytania, istnieje powód, by sądzić, że używasz MySQL, a MINUS lub EXCEPT nie są tam obsługiwane.
Innym wariantem jest użycie NOT EXISTS
predykatu:
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 = ?
);
Tj. Wybory, w których nie istnieje, głosuje użytkownik. NOT IN
Orzecznik może być stosowane w podobny sposób. Ponieważ mogą występować wartości zerowe, warto zauważyć, że semantyka różni się pomiędzy IN i EXISTS.
Wreszcie możesz użyć sprzężenia zewnętrznego
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;
Jeśli nie ma wierszy pasujących do predykatu ON, wszystkie kolumny z głosów zostaną w wyniku zastąpione przez null. Możemy zatem sprawdzić, czy jakaś kolumna z głosów jest pusta w klauzuli WHERE. Ponieważ obie kolumny w głosowaniu mogą być zerowe, musisz zachować ostrożność.
Najlepiej jest naprawić tabele, aby nie musieć radzić sobie z problemami spowodowanymi przez wartości zerowe:
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)
);