事情的起因
我的解
WITH alls AS(
SELECT a.id,COUNT(1) AS num FROM (
SELECT c.id,c.p_id FROM Tree c
WHERE c.id NOT IN(SELECT id FROM Tree WHERE p_id IS NULL)
UNION ALL
SELECT d.p_id,d.id FROM Tree d
WHERE d.p_id NOT IN(SELECT id FROM Tree WHERE p_id IS NULL)
)AS a
GROUP BY a.id
UNION
SELECT id,0 FROM Tree WHERE p_id IS NULL
)
SELECT id,(CASE WHEN num>1 THEN 'Inner' WHEN num=0 THEN 'Root' WHEN num=1 THEN 'Leaf' end ) AS [type] FROM alls
WHERE id IS NOT NULL
我的解注解
写的很复杂,加入了很多不需要的查询,因为从一开始,思路就有问题
1.首先null一定就是根节点
2.没有下级的一定是子节点
3.有上级也有下级的就什么节点也不是,也可以理解为有下级的
可不可以理解为两个列合并,如果是null的就是根节点,
如果出现了2次或者以上那他就是什么节点都不是
如果只出现了一次那它就是子节点
这是我审完题后的注解,但是很明显有重复的因为其实第三点,根节点也可以出现,这就导致我后面写的很复杂,可能会有些小伙伴讲,最后不是写出来了吗,但是不管是玩算法的,还是编程的其实都会追求性能,这么多查询,很明显,是很拖累性能的,而且,如果一开始想错了,容易出现南辕北辙,后期通过代码去补救的话,其实蛮痛苦的
最优解
select distinct a.id,
case when a.p_id is null then 'Root'
when b.id is null then 'Leaf'
else 'Inner' end type
from Tree a
left join Tree b
on b.p_id=a.id
最优解注解
1.在p_id列为null的就是根节点
2.id存在p_id不存在的就是子节点
3.同时存在的就是内部节点