加入时没有得到预期的结果

时间:2011-11-12 10:32:51

标签: sql sql-server sql-server-2008

我想显示没有孩子的#acc,结果必须是B,C,D,E,但只能获得B,C,D

create table #acc (mainid int,name nvarchar(20),subid int)

    insert into #acc values(1,'A',0)
    insert into #acc values(2,'B',1)
    insert into #acc values(3,'C',1)
    insert into #acc values(4,'D',1)
    insert into #acc values(5,'E',0)

    select  A.name from #acc
    A inner join #acc B
    on 
    A.subid   = B.mainid    

    drop table #acc 

2 个答案:

答案 0 :(得分:1)

首先,我认为您应该将subid列重命名为superidparentid或类似的内容,因为它是BC &安培; D sub -items A,而不是相反。B也许不一致的命名正是您查询结果似乎难以理解的原因,或者为什么您发现难以构造返回正确结果的查询。

您的查询实质上是返回其他项目的子项目。他们自己可能有也可能没有自己的孩子。例如,如果CDB有孩子,那么除了CDLEFT JOIN之外,您的查询还会返回这些孩子。这似乎不是你想要的。

这里你需要的不是内连接而是 anti -join。这是根据匹配的事实返回结果的时间。反连接可以以不同的方式实现:

  1. 使用IS NULL + SELECT A.* FROM #acc A LEFT JOIN #acc B ON A.mainid = B.subid WHERE B.mainid IS NULL 检查:

    mainid

    这里我们将表连接到自身并返回右侧没有匹配的连接的左侧(即返回subid列中从未找到NOT EXISTS值的行)。

  2. 使用SELECT * FROM #acc A WHERE NOT EXISTS ( SELECT * FROM #acc B WHERE A.mainid = B.subid )

    #acc

    此查询可以这样解释:当该行的mainid与任何其他行subid之间不存在匹配时,返回NOT IN的每一行。

    < / LI>
  3. 使用SELECT * FROM #acc WHERE mainid NOT IN ( SELECT subid FROM #acc )

    mainid

    这在我看来最直接(虽然不一定最有效):返回subid不在所有现有NULL值列表中的行。如果您使用0而不是subid作为根项'… WHERE subid IS NOT NULL 值,则还必须通过将此过滤器添加到子查询来修改最后一个查询:

    {{1}}

    否则会无法正常工作。

  4. 您可能还想阅读此主题:

答案 1 :(得分:0)

这样做

      select * from
        (select  A.mainid , A.name  from #acc
A left join #acc B
on A.subid   = B.mainid  ) as m where  m.mainid not in (select subid from #acc)