I betragtning af disse begrænsninger er der ingen måde. I et sådant tilfælde ville du enten hente alle træet og byg en 'bakke' klientside, eller udfør rekursive forespørgsler, hvad end der ville være mest effektivt i det specifikke tilfælde.
Med den yderligere begrænsning at have et fast antal hierarkiniveauer , kan du gøre dette med en multipel JOIN.
I det generelle tilfælde er der flere strukturændringer for at tillade at overvinde disse begrænsninger. I praksis slækker du på begrænsningen "DETTE er min tabelstruktur", hvilket tillader tilføjelse af yderligere felter.
For eksempel kan du supplere nodestrukturen med en left_id
værdi, og sørg for, at alle node-id'er er i rækkefølge, når du besøger træets dybde først:
1 --- 2 -+- 3 -+- 4
| |
| +- 5
+- 6 --- 7
I dette tilfælde vil node 3 gemme værdien "5", node 6 ville lagre værdien "7", og node 2 ville også lagre værdien "7". Hver node gemmer i LeftID det maksimale mellem sine børns LeftID'er og sit eget ID .
Så barnløse noder har LeftID svarende til deres ID'er. Node 1 vil have LeftID 7, da det er LeftID af 2, som fik det fra 6.
I denne situation tæller noder er let, hvis der ikke er huller i sekvensen; alle efterkommere af en node er de noder, hvis ID er mellem startknudepunktets ID og dets LeftID; og blade identificeres ved at have LeftID lig med ID.
Så "alle blade, der falder fra node id 17" ville være
SELECT child.*FROM table AS parentJOIN tabel AS childON (child.id> parent.id AND child.id <=parent.leftid ) /* Descendant /WHERE child.id =child.leftid / Blad /AND parent.id =17; / Forælder er 17
Denne struktur er besværlig at vedligeholde, hvis du vil være i stand til at beskære og forgrene, da du skal omnummerere alle noder mellem beskæringspunktet op til grenpunktet, såvel som de flyttede noder.
En anden mulighed, hvis du kun er interesseret i at tælle, er at holde en børnetæller. Dette kan opretholdes ved at opdatere det iterativt, vælge alle blade og sætte deres tæller til 0 (du identificerer blade gennem en LEFT JOIN); derefter alle de forældre med NULL-tællere, der har børn med ikke-NULL-tællere, opdaterer deres tællere til SUM()
af børnetællere plus COUNT()
af børn selv; og fortsætter indtil antallet af opdaterede rækker bliver nul, for alle noder har ikke-NULL-tællere. Efter en beskære-og-gren skal du bare sætte alle tællere til NULL og gentage.
Denne sidste tilgang koster en reflekterende sammenføjning for hvert hierarkiniveau.