sql >> Databasteknik >  >> RDS >> Mysql

MySQL:Hur man hittar löv i specifik nod

Det finns inget sätt att göra detta i en enda fråga. Även om det fanns skulle det förmodligen vara väldigt ineffektivt.

Vi kan göra det med en lagrad procedur och en loop. Med de index du lagt till borde det också gå ganska snabbt. Detta använder två tabeller som väljer noderna från inmatningstabellen (A) och infogar noden och deras barn i (B). Den byter sedan ut B mot A och upprepar tills det inte finns fler icke-bladsnoder i A. Det fina är att loopiterationer bara skulle vara lika många som nivåerna mellan ingångsnoden och den sista lövnoden, vilket i de flesta fall är förmodligen inte så djupt. Denna lagrade procedur skulle vara snabbare än att göra den externt i kod.

FYI Jag hade svårt med min installation att hantera tillfälliga tabeller, om du får ett "fel 2" så ta bort det tillfälliga nyckelordet.

delimiter $$
drop procedure if exists GetLeafNodes $$
create procedure GetLeafNodes(nodeid int)
begin
declare N int default 1;

-- create two working sets of IDs, we'll go back and forth between these two sets
drop temporary table if exists A;
drop temporary table if exists B;
create temporary table A(node int, child int);
create temporary table B(node int, child int);

-- insert our single input node into the working set
insert into A values (null, nodeid);

while (N>0) do
  -- keep selecting child nodes for each node we are now tracking
  -- leaf nodes will end up with the child set to null
  insert into B
  select ifnull(A.child,A.node), tree.ID
    from A
    left outer join DATA_TREE as tree on A.child=tree.parent_id;

  -- now swap A and B
  rename table A to temp, B to A, temp to B;

  -- remove non-leaf nodes from table B
  delete from B;

  -- exit when there are no longer any non-leaf nodes in A
  set N=(select count(*) from A where child is not null);
end while;

-- now output our list of leaf nodes
select node from A;

drop temporary table A;
drop temporary table B;
end $$
DELIMITER ;
call GetLeafNodes(4);

Jag använde följande provuppsättning för att testa:

CREATE TABLE `DATA_TREE` (
  `ID` int(11) NOT NULL,
  `PARENT_ID` int(11) NOT NULL,
  PRIMARY KEY (`ID`),
  UNIQUE KEY `ID_UNIQUE` (`ID`),
  KEY `fk_DATA_TREE_1_idx` (`PARENT_ID`)
) ENGINE=InnoDB
;

insert into DATA_TREE values
(1,0),(2,1),(3,1),(4,1),(5,3),(6,3),(7,4),(8,4),(9,4),(10,6),(11,6),(12,7),(13,9),(14,9),(15,12),(16,12),(17,12),(18,14);



  1. Hur man buntar cx_oracle med Pyinstaller

  2. Minska minnesförbrukningen för mysql på [email protected] mikroinstanser

  3. MySQL LIKE + php sprintf

  4. SQL Server Trigger:Förståelse och alternativ