不在,并且存在不按预期工作

时间:2015-09-15 12:15:24

标签: sql sql-server-2005

所有。我的问题很简单,但我无法通过myselft解决。 我有2个表:et_pics.ob_no其中ob_no是用户id和et_thanks_2014其中thnk.e_to是et_pics.ob_no的链接。 我需要在et_phanks_2014中找到e_to中缺席的et_pics中的ob_no。

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预测来解决它:

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)

但两者都没有返回。为什么呢?

4 个答案:

答案 0 :(得分:4)

您需要相关性。例如:

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

如果没有相关性,则假定表不为空,则子查询(可能)始终返回至少一行。因此,not exists始终返回false。

等效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_to 永远 NULL,那么它将永远不会返回true,因此所有内容都将被过滤。因此,出于语义原因,我倾向于推荐NOT INLEFT JOIN

另请注意,使用DISTINCTIN的子查询中不需要EXISTS

答案 1 :(得分:1)

我相信你应该使用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;

答案 2 :(得分:1)

你必须添加一个拟合的Where子句:

<web-app id="WebApp_ID" version="2.5"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <display-name>myApp</display-name>
    <error-page>
        <error-code>400</error-code>
        <location>/errorPage400.xhtml</location>
    </error-page>
    <error-page>
        <error-code>401</error-code>
        <location>/errorPage401.xhtml</location>
    </error-page>
    <error-page>
        <error-code>404</error-code>
        <location>/errorPage404.xhtml</location>
    </error-page>
    <error-page>
        <error-code>500</error-code>
        <location>/errorPage500.xhtml</location>
    </error-page>
    <error-page>
        <exception-type>java.lang.Throwable</exception-type>
        <location>/errorPage.xhtml</location>
    </error-page>

答案 3 :(得分:1)

为什么不简单地使用&#34; EXCEPT&#34;。查询将是一些像: SELECT ob_no FROM et_pics EXCEPT SELECT e_to FROM et_thanks_2014;