在分层树中查找叶节点

时间:2008-10-15 00:20:41

标签: sql database tree

我的数据库中有一个存储树结构的表。以下是相关领域:

mytree (id, parentid, otherfields...)

我想查找所有叶节点(即id不是另一条记录parentid的任何记录)

我试过这个:

SELECT * FROM mytree WHERE `id` NOT IN (SELECT DISTINCT `parentid` FROM `mytree`)

但那返回了一个空集。奇怪的是,删除“NOT”会返回所有非叶节点的集合。

谁能看到我出错的地方?

更新:感谢答案人们,他们都是正确的,并为我工作。我已经接受了丹尼尔的,因为它也解释了为什么我的查询不起作用(NULL的事情)。

5 个答案:

答案 0 :(得分:20)

您的查询无效,因为子查询包含NULL。以下略有修改对我有用:

SELECT * FROM `mytree` WHERE `id` NOT IN (
    SELECT DISTINCT `parentid` FROM `mytree` WHERE `parentid` IS NOT NULL)

答案 1 :(得分:6)

不知道为什么你的查询不起作用。左外连接语法中的相同内容 - 以这种方式试试吗?

select a.*
from mytree a left outer join
     mytree b on a.id = b.parentid
where b.parentid is null

答案 2 :(得分:4)

SELECT * FROM mytree AS t1
LEFT JOIN mytree AS t2 ON t1.id=t2.parentid
WHERE t2.parentid IS NULL

答案 3 :(得分:0)

从mytree中选择*,其中id不在(从parentid不为空的mytree中选择不同的parentid)

http://archives.postgresql.org/pgsql-sql/2005-10/msg00228.php

答案 4 :(得分:-2)

我的表结构是

memberid    MemberID    joiningposition packagetype
RPM00000    NULL          Root                free
RPM71572    RPM00000       Left           Royal
RPM323768   RPM00000       Right              Royal
RPM715790   RPM71572       Left            free
RPM323769   RPM71572      Right            free
RPM715987   RPM323768      Left             free
RPM323985   RPM323768      Right               free
RPM733333   RPM323985     Right            free
RPM324444   RPM715987     *emphasized text*Right               Royal

-

ALTER procedure [dbo].[sunnypro]
as
DECLARE @pId varchar(40) = 'RPM00000';
Declare @Id int
set @Id=(select id from registration where childid=@pId) 
begin




-- Recursive CTE
    WITH R AS
     (



SELECT 

    BU.DateofJoing,
    BU.childid,
    BU.joiningposition,
    BU.packagetype
    FROM registration AS BU
    WHERE
    BU.MemberID = @pId and
   BU.joiningposition IN ('Left', 'Right')
    or BU.packagetype in('Royal','Platinum','Majestic')
     and BU.Id>@id
    UNION All

-- Recursive part
SELECT

     BU.DateofJoing,
     BU.childid,
     R.joiningposition,
    BU.packagetype


    FROM R
    JOIN registration AS BU
    ON BU.MemberID = R.childid
    WHERE
    BU.joiningposition IN ('Left', 'Right') and
  BU.packagetype in('Royal','Platinum','Majestic')
 and BU.Id>@id
)

INSERT INTO Wallatpayout
       (childid
       ,packagetype

       ,joiningposition
       ,DateofJoing
       ,Total)

-- Final groups of nodes found
SELECT top 3

R.childid,
R.packagetype,
R.joiningposition,
R.DateofJoing,
Total = COUNT_BIG(*)
FROM R where R.packagetype in('Royal','Platinum','Majestic')
GROUP BY R.childid,
R.joiningposition,
R.DateofJoing,
R.packagetype
OPTION (MAXRECURSION 0);
end