sql >> Databáze >  >> RDS >> Mysql

Dotazování na počet položek stromu

Vzhledem k těmto omezením neexistuje žádný způsob. V takovém případě byste buď načetli vše strom a vytvořit „kopec“ na straně klienta nebo provádět rekurzivní dotazy, podle toho, co by bylo v konkrétním případě nejvýkonnější.

S dalším omezením pevného počtu úrovní hierarchie , můžete to udělat pomocí vícenásobného JOIN.

V obecném případě existuje několik modifikací struktury, které umožňují překonat tato omezení. V praxi uvolníte omezení „THIS is my table structure“, což umožňuje přidání dalších polí.

Můžete například doplnit strukturu uzlu pomocí left_id a zajistěte, aby všechna ID uzlů byla v pořadí, když navštívíte hloubku stromu:

1 --- 2 -+- 3 -+- 4
         |     |
         |     +- 5
         +- 6 --- 7

V tomto případě by uzel 3 uložil hodnotu "5", uzel 6 by uložil hodnotu "7" a uzel 2 by také uložil hodnotu "7". Každý uzel ukládá v LeftID maximum mezi svými podřízenými LeftID a svým vlastním ID .

Takže bezdětné uzly mají LeftID rovné jejich ID. Uzel 1 bude mít LeftID 7, protože to je LeftID 2, které ho získalo z 6.

V této situaci počítám uzly je snadné, pokud v sekvenci nejsou žádné díry; všichni potomci uzlu jsou ty uzly, jejichž ID je mezi ID počátečního uzlu a jeho LeftID; a listy jsou identifikovány tak, že LeftID se rovná ID.

Takže "všechny listy sestupně z node id 17" by byly

SELECT child.*FROM table AS parentJOIN table AS childON (child.id> parent.id AND child.id <=parent.leftid ) /* Potomek /WHERE child.id =child.leftid / List /AND parent.id =17; / Rodičovi je 17

Tato struktura je nepohodlná na údržbu, pokud chcete mít možnost provádět ořezávání a větvení, protože musíte přečíslovat všechny uzly mezi bodem ořezávání až bodem větvení, stejně jako přečíslované uzly.

Další možností, pokud vás zajímá pouze počítání, je ponechat si dětské počítadlo. To lze udržovat opakovanou aktualizací, výběrem všech listů a nastavením jejich počítadla na 0 (listy identifikujete pomocí LEFT JOIN); pak všichni rodiče s nulovými čítači, kteří mají potomky s jinými čítači než NULL, aktualizují jejich čítače na SUM() dětských počítadel plus COUNT() samotných dětí; a pokračuje, dokud se počet aktualizovaných řádků nestane nulou, protože všechny uzly mají čítače bez NULL. Po prořezávání a větvení stačí nastavit všechny čítače na NULL a opakovat.

Tento poslední přístup stojí reflexní spojení pro každou úroveň hierarchie.



  1. Jak používat připravené příkazy v dotazech s klauzulí IN v PHP

  2. Pouze jeden klíč ze složeného primárního klíče jako cizí klíč

  3. Získejte aktualizovanou hodnotu v MySQL namísto ovlivněných řádků

  4. Spouštěcí a zastavovací skripty EBS R12