usando - mysql arbol jerarquico
Buscar nodos de hojas en el árbol jerárquico (5)
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 hoja (es decir, cualquier registro cuyo id
no sea el parentid
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, eliminar el "NO" devuelve el conjunto de todos los nodos de hoja.
¿Alguien puede ver dónde me estoy equivocando?
Actualización: Gracias por las respuestas, todos han sido correctos y han funcionado para mí. Acepté el de Daniel porque también explica por qué mi consulta no funcionó (lo NULO).
No hay idea de por qué su consulta no funcionó. Aquí está lo idéntico en la sintaxis de la combinación externa izquierda: pruébalo de esta manera.
select a.*
from mytree a left outer join
mytree b on a.id = b.parentid
where b.parentid is null
Seleccione * de mytree donde id no esté (seleccione parentid distinto de mytree donde parentid no sea nulo)
http://archives.postgresql.org/pgsql-sql/2005-10/msg00228.php
Su consulta no funcionó porque la subconsulta incluye NULL
. La siguiente ligera modificación me funciona:
SELECT * FROM `mytree` WHERE `id` NOT IN (
SELECT DISTINCT `parentid` FROM `mytree` WHERE `parentid` IS NOT NULL)
SELECT * FROM mytree AS t1
LEFT JOIN mytree AS t2 ON t1.id=t2.parentid
WHERE t2.parentid IS NULL
mi estructura de mesa 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