2011-11-12 93 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 
    

    否則就無法正常工作。

您可能還需要閱讀此線程:

相關問題