在一个简单的投票系统中
CREATE TABLE elections (
election_id int(11) NOT NULL AUTO_INCREMENT,
title varchar(255),
CREATE TABLE votes (
election_id int(11),
user_id int(11),
FOREIGN KEYs
Run Code Online (Sandbox Code Playgroud)
为了获取用户投票的选举列表,使用以下 JOIN
SELECT * FROM elections
JOIN votes USING(election_id)
WHERE votes.user_id='x'
Run Code Online (Sandbox Code Playgroud)
但是如何获取用户未投票的选举列表?
Spa*_*arr 29
使用您现有的查询来获取您想要的列表的反面。然后可以通过 NOT IN 检查该列表以获得所需的列表。
SELECT * FROM elections WHERE election_id NOT IN (
SELECT elections.election_id from elections
JOIN votes USING(election_id)
WHERE votes.user_id='x'
)
Run Code Online (Sandbox Code Playgroud)
dru*_*zin 20
使用外连接:
select e.election_id, e.title, v.user_id
from Elections e
LEFT OUTER JOIN votes v ON v.election_id = e.election_id and v.user_id = @userid
Run Code Online (Sandbox Code Playgroud)
如果没有为特定选举投票,则 UserId 将为空,否则会显示
如果您只想列出没有任何投票的选举,您可以这样做:
select *
from elections e
where election_id NOT IN
(select election_id
from votes
where user_id = @userid
)
Run Code Online (Sandbox Code Playgroud)
有很多方法可以实现您的要求。也许最直接的方法是使用纯面向集合的方法:
select election_id from elections
minus -- except is used instead of minus by some vendors
select election_id from votes where user_id = ?
Run Code Online (Sandbox Code Playgroud)
从选举集中,我们删除用户投票的选举。结果可以与选举结合以获得选举的标题。即使您没有标记您的问题,也有理由相信您正在使用 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 = ?
);
Run Code Online (Sandbox Code Playgroud)
即不存在用户投票的选举。该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;
Run Code Online (Sandbox Code Playgroud)
如果没有与 ON 谓词匹配的行,则来自 votes 的所有列在结果中都替换为 null。因此,我们可以检查 WHERE 子句中来自 votes 的任何列是否为空。由于投票中的两列都可能为空,因此您需要小心。
理想情况下,您应该修复您的表,以便您不必处理由空值引起的问题:
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)
);
Run Code Online (Sandbox Code Playgroud)