有很多方法可以实现您的要求。也许最直接的方法是使用纯面向集合的方法:
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
谓词可以以类似的方式被使用。由于可能涉及空值,因此值得注意的是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引起的问题:
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)
);