繁体   English   中英

给定两个具有公共字段F的表A和B,我如何有效地找到A中所有B中不存在的F?

[英]Given two tables A and B with a common field F, how do I efficiently find all F in A that are not present in B?

我有一个投票系统,我正在尝试为MySQL写一个查询,该查询将检测完成的投票,以便将电子邮件发送给投票的创建者。 当(1)他们的时间用完(已经很容易解决)时,或(2)当所有选民都投票时,投票就完成了。

有两个与此相关的表。 第一个表是“投票”,其中描述了每个投票并具有唯一的“ vote_id”。 第二张表是“门票”。 在投票创建时,每个参与者都会创建一个票证(其中包含一些身份验证信息)。 每个票证都有一个“ vote_id”字段,该字段与“ votes”表中的字段相对应。 因此,基本上,随着人们的投票,他们相应的票证将从票证表中删除。 这意味着给定“ vote_id”的“票证”中的行数对应于未投票的人数。

首先,我去做这样的事情:

SELECT votes.vote_id
FROM votes, tickets
WHERE votes.vote_id=tickets.vote_id
AND (votes.completion_timestamp < NOW())
HAVING (COUNT(tickets.vote_id) = 0)

但是后来我意识到...由于“ votes.vote_id = tickets.vote_id”这一行...我想这意味着那些没有未付票证的票将被忽略。 我可以想到许多效率低下的方法来执行此操作,但是我想在MySQL中有一种方法可以执行此操作?

问题的概括:给定两个具有共同字段F的表A和B,我如何找到A中所有B中不存在的F?

为了在MySQL中有效地做到这一点,需要一个技巧:

select v.*
from votes v
where votes.completion_timestamp < NOW() and
      not exists (select 1 from tickets t where t.vote_id = v.vote_id)

您拥有的SQL不太正确。 以下版本应该工作:

SELECT distinct votes.vote_id
FROM votes left outer join
     tickets
     on votes.vote_id=tickets.vote_id
where votes.completion_timestamp < NOW()) and
      tickets.vote_id is null 

MySQL文档(http://dev.mysql.com/doc/refman/5.0/en/subquery-optimization-with-exists.html)中广泛讨论了EXISTS与IN结合使用子查询的问题。 与左外部连接的区别在于两点。 加入策略并增加I / O。

我不知道JOIN策略对于左外部联接是否有所不同。 我推测它不应该比EXISTS版本更糟。 不过,第二点是,左外部联接创建了一个输出集,该输出集可能使行数成倍增加。 EXISTS版本无法执行此操作。

阅读文档后,以下操作可能会更有效:

select v.*
from votes v
where votes.completion_timestamp < NOW() and
      not exists (select 1 from tickets t where t.vote_id = v.vote_id limit 1)

该限制应该使遇到的第一行以外的任何评估短路。

这样的事情将返回您期望的结果:

select votes.vote_id
from votes
    left outer join tickets on votes.vote_id = tickets.vote_id
where tickets.ticket_id is null or votes.completion_timestamp < NOW()

假定tickets.ticket_idtickets表的主键,并且不能为NULL。
该查询通过在票证与票证之间进行左外部tickets.ticket_id并在其中票证tickets.ticket_id必须为NULL的条件下利用了这一事实。 只有在tickets表中没有该票证的票证时,才会发生这种情况。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM