sql >> Database teknologi >  >> RDS >> Mysql

Forespørgsel om en optælling af elementer i et træ

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.



  1. Hvordan henter jeg JSON-data fra MySQL?

  2. Udefineret reference til MySQL-biblioteker ved hjælp af g++

  3. Enhver måde at vælge fra MySQL-tabel, hvor et felt ender med et bestemt tegn/tal?

  4. Hvis erklæring inden for Hvor-klausulen