sql >> Databasteknik >  >> RDS >> Mysql

Fråga om antalet objekt i ett träd

Med tanke på dessa begränsningar finns det inget sätt. I ett sådant fall skulle du antingen hämta alla trädet och bygg en "backe"-klientsida, eller utför rekursiva frågor, vad som än skulle fungera bäst i det specifika fallet.

Med den ytterligare begränsningen att ha ett fast antal hierarkinivåer , kan du göra detta med en multipel JOIN.

I det allmänna fallet finns det flera strukturmodifieringar för att tillåta att övervinna dessa begränsningar. I praktiken lättar du på begränsningen "DETTA är min tabellstruktur", vilket tillåter tillägg av ytterligare fält.

Du kan till exempel komplettera nodstrukturen med en left_id värde och se till att alla nod-ID:n är i sekvens när du besöker trädet depth-first:

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

I detta fall skulle nod 3 lagra värdet "5", nod 6 skulle lagra värdet "7", och nod 2 skulle också lagra värdet "7". Varje nod lagrar maximalt i LeftID mellan sina barns LeftID:n och sitt eget ID .

Så barnlösa noder har LeftID lika med deras ID. Nod 1 kommer att ha LeftID 7 eftersom det är LeftID för 2, som fick det från 6.

I den här situationen räknas noder är lätt om det inte finns några hål i sekvensen; alla avkomlingar till en nod är de noder vars ID är mellan startnodens ID och dess LeftID; och blad identifieras genom att ha LeftID lika med ID.

Så "alla blad som kommer från nod id 17" skulle vara

SELECT child.*FROM table AS parentJOIN-tabell AS childON (child.id> parent.id AND child.id <=parent.leftid ) /* Descendant /WHERE child.id =child.leftid / Blad /AND parent.id =17; / Förälder är 17

Den här strukturen är besvärlig att underhålla om du vill kunna beskära och förgrena, eftersom du måste numrera om alla noder mellan beskärningspunkten upp till grenpunkten, såväl som de flyttade noderna.

En annan möjlighet om du bara är intresserad av att räkna är att ha en barndisk. Detta kan underhållas genom att uppdatera det iterativt, välja alla blad och ställa in deras räknare till 0 (du identifierar blad genom en LEFT JOIN); sedan alla föräldrar med NULL-räknare som har barn med icke-NULL-räknare, uppdatera sina räknare till SUM() av barnräknare plus COUNT() av barnen själva; och fortsätter tills antalet uppdaterade rader blir noll, för alla noder har icke-NULL-räknare. Efter en beskära-och-gren, ställer du bara in alla räknare på NULL och upprepar.

Detta sista tillvägagångssätt kostar en reflekterande sammanfogning för varje hierarkinivå.



  1. CAST vs ssis dataflöde implicit konverteringsskillnad

  2. Oracle sammanfogar sträng- och nummerexempel

  3. Konvertera MySQL-tabell med felaktigt kodad data till UTF-8

  4. Hur man lägger till autoinkrement-id enligt en grupp i mysql