Pregunta

Tengo una tabla en mi base de datos que almacena una estructura de árbol. Aquí están los campos relevantes:

mytree (id, parentid, otherfields...)

Quiero encontrar todos los nodos de hoja (es decir, cualquier registro cuyo id no sea el parentid de otro registro)

He intentado esto:

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

Pero eso devolvió un conjunto vacío. Extrañamente, eliminando el " NOT " devuelve el conjunto de todos los nodos que no son hojas.

¿Alguien puede ver dónde me equivoco?

Actualización: Gracias por las respuestas, todos han sido correctos y han funcionado para mí. He aceptado la de Daniel ya que también explica por qué mi consulta no funcionó (lo que es NULO).

¿Fue útil?

Solución

Su consulta no funcionó porque la subconsulta incluye NULL . La siguiente modificación leve funciona para mí:

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

Otros consejos

No hay idea de por qué su consulta no funcionó. Esto es lo mismo en la sintaxis de la combinación externa izquierda: inténtelo de esta manera.

select a.*
from mytree a left outer join
     mytree b on a.id = b.parentid
where b.parentid is null
SELECT * FROM mytree AS t1
LEFT JOIN mytree AS t2 ON t1.id=t2.parentid
WHERE t2.parentid IS NULL

Seleccione * de mytree donde id no está en (seleccione un parentid distinto de mytree donde parentid no es nulo)

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

la estructura de mi tabla es

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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top