我想显示没有孩子的#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
答案 0 :(得分:1)
首先,我认为您应该将subid
列重命名为superid
或parentid
或类似的内容,因为它是B
,C
&安培; D
sub -items A
,而不是相反。B
也许不一致的命名正是您查询结果似乎难以理解的原因,或者为什么您发现难以构造返回正确结果的查询。
您的查询实质上是返回其他项目的子项目。他们自己可能有也可能没有自己的孩子。例如,如果C
,D
或B
有孩子,那么除了C
,D
和LEFT JOIN
之外,您的查询还会返回这些孩子。这似乎不是你想要的。
这里你需要的不是内连接而是 anti -join。这是根据不匹配的事实返回结果的时间。反连接可以以不同的方式实现:
使用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
值的行)。
使用SELECT *
FROM #acc A
WHERE NOT EXISTS (
SELECT *
FROM #acc B
WHERE A.mainid = B.subid
)
:
#acc
此查询可以这样解释:当该行的mainid
与任何其他行subid
之间不存在匹配时,返回NOT IN
的每一行。
使用SELECT *
FROM #acc
WHERE mainid NOT IN (
SELECT subid
FROM #acc
)
:
mainid
这在我看来最直接(虽然不一定最有效):返回subid
不在所有现有NULL
值列表中的行。如果您使用0
而不是subid
作为根项'…
WHERE subid IS NOT NULL
值,则还必须通过将此过滤器添加到子查询来修改最后一个查询:
{{1}}
否则会无法正常工作。
您可能还想阅读此主题:
答案 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)