16

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

mytree (id, parentid, otherfields...)

我想找到所有的叶子节点(即任何id不是另一个记录的记录parentid

我试过这个:

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

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

谁能看到我哪里出错了?

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

4

5 回答 5

22

您的查询无效,因为子查询包括NULL. 以下轻微修改对我有用:

SELECT * FROM `mytree` WHERE `id` NOT IN (
    SELECT DISTINCT `parentid` FROM `mytree` WHERE `parentid` IS NOT NULL)
于 2008-10-15T00:30:26.750 回答
8

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

select a.*
from mytree a left outer join
     mytree b on a.id = b.parentid
where b.parentid is null
于 2008-10-15T00:28:33.167 回答
5
SELECT * FROM mytree AS t1
LEFT JOIN mytree AS t2 ON t1.id=t2.parentid
WHERE t2.parentid IS NULL
于 2008-10-15T00:31:09.587 回答
1
Select * from mytree where id not in (Select distinct parentid from mytree where parentid is not null)

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

于 2008-10-15T00:41:31.940 回答
-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
于 2015-10-05T20:25:01.640 回答