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 に答える