2011-11-12 56 views
1

我想显示的是,这里没有子结果一定是B,C,d,E,但得到B,C#acc,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 
+0

什么是A和E之间的区别?你为什么期望得到E而不是A? – JJJ

+0

@Juhana A有孩子但E不 – Nighil

回答

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) 
1

首先,我认为你应该在subid列重命名为superidparentid或类似的东西,因为它是BC & D-A的项目,而不是相反。也许命名不一致就是为什么你的查询结果看起来难以理解,或者你为什么难以构建返回正确结果的查询。

您的查询基本上是返回一些其他项目的子项目。他们自己可能有也可能没有自己的孩子。例如,如果B,CD有孩子,则除B,CD之外,您的查询还会返回这些孩子。这似乎并不完全是你在做什么。

你在这里需要的不是内连接,而是 -join。这是结果返回的基础上事实有不匹配匹配。反联接可以用不同的方式来实现:

  1. 使用LEFT JOIN + IS NULL检查:

    SELECT A.* 
    FROM #acc A 
        LEFT JOIN #acc B ON A.mainid = B.subid 
    WHERE B.mainid IS NULL 
    

    在这里,我们加入了表本身和返回的左侧加入了右侧哪里没有匹配(即返回mainid的值,这些值在subid列中从未找到)。

  2. 使用NOT EXISTS

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

    这种查询可以解释这样的:从#acc当不存在该行的mainid和任何其他行的subid之间的匹配返回每一行。

  3. 使用NOT IN

    SELECT * 
    FROM #acc 
    WHERE mainid NOT IN (
        SELECT subid 
        FROM #acc 
    ) 
    

    这在我看来,最简单的(尽管不一定是最有效的):回行,其中mainid并不适用于所有现有subid值的列表。如果您使用NULL!而非0为根项目subid值,你也不得不加入这个过滤器的子查询修改上次查询:

    … 
    WHERE subid IS NOT NULL 
    

    否则就无法正常工作。

您可能还需要阅读此线程:

相关问题