Not in and Exists 没有像我预期的那样工作

Not in and Exists not working as i expect

全部。我的问题很简单,但我自己无法解决。 我有 2 个表:et_pics.ob_no,其中 ob_no 是用户 ID,et_thanks_2014,其中 thnk.e_to 是 link 到 et_pics.ob_no。 我需要找出 et_pics 中的 ob_no 谁缺席了 et_thanks_2014 中的 e_to。

SELECT pics.ob_no, thnk.e_to FROM et_pics pics 
left join et_thanks_2014 thnk on thnk.e_to = pics.ob_no
WHERE e_to is null

此代码有效,但我认为这不是解决我的任务的最佳方法。我试图用 IN predict:

解决它
SELECT pics.ob_no FROM et_pics pics 
WHERE pics.ob_no  in ((SELECT e_to FROM et_thanks_2014))

不存在

SELECT ob_no from et_pics
WHERE not exists (SELECT DISTINCT (e_to) FROM et_thanks_2014 thnk)

但两者都returns什么都没有。为什么?

你需要相关性。例如:

SELECT ob_no
from et_pics
WHERE not exists (SELECT 1 FROM et_thanks_2014 thnk WHERE thnk.e_to = pics.ob_no);

如果没有相关性,假设 table 不为空,您的子查询(大概)总是 return 至少一行。因此,not exists 总是 return 为假。

等价于not in是:

SELECT ob_no
FROM et_pics
WHERE pics.ob_no NOT IN (SELECT thnk.e_to FROM et_thanks_2014 thnk);

几乎是等价的。但是,如果 thnk.e_toever NULL,那么它永远不会 return 为真,因此所有内容都将被过滤。因此,出于语义原因,我倾向于推荐 NOT INLEFT JOIN

另请注意,在使用 INEXISTS 的子查询中,DISTINCT 是不必要的。

我相信您应该像下面那样使用 NOT IN,因为您正在尝试获取不常见的值

SELECT pics.ob_no FROM et_pics pics 
WHERE pics.ob_no  NOT IN (SELECT e_to FROM et_thanks_2014);

此外,我不确定您为什么认为您的 LEFT JOIN 解决方案不是最佳解决方案。

SELECT pics.ob_no, 
thnk.e_to 
FROM et_pics pics 
left join et_thanks_2014 thnk on thnk.e_to = pics.ob_no
WHERE thnk.e_to is null;

您必须添加一个合适的 Where 子句:

SELECT pics.ob_no FROM et_pics pics 
WHERE pics.ob_no  in ((SELECT e_to FROM et_thanks_2014 thnk WHERE thnk.e_to = pics.ob_no))

SELECT pics.ob_no from et_pics pics
WHERE not exists (SELECT DISTINCT (e_to) FROM et_thanks_2014 thnk WHERE thnk.e_to = pics.ob_no)

为什么不简单地使用 "EXCEPT"。查询会是这样的: SELECT ob_no 来自 et_pics 除了 SELECT e_to 来自 et_thanks_2014;