あなたが求めていることを達成する方法はたくさんあります。おそらく最も簡単な方法は、純粋にセット指向のアプローチを使用することです。
select election_id from elections
minus -- except is used instead of minus by some vendors
select election_id from votes where user_id = ?
一連の選挙から、ユーザーが投票したものを削除します。結果を選挙と組み合わせて、選挙のタイトルを取得できます。質問にタグを付けていませんが、MySQLを使用していると信じる理由があり、MINUSまたはEXCEPTはそこでサポートされていません。
別の変形は、NOT EXISTS
述語を使用することです:
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 = ?
);
すなわち、それが存在しない選挙は、ユーザーからの投票です。NOT IN
述語は、同様の方法で使用することができます。nullが含まれている可能性があるため、INとEXISTSでセマンティクスが異なることに注意する価値があります。
最後に、外部結合を使用できます
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;
ON述語に一致する行がない場合、投票のすべての列は結果でnullに置き換えられます。したがって、WHERE句で票の列がnullであるかどうかを確認できます。投票の両方の列がヌルである可能性があるため、注意する必要があります。
理想的には、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)
);