Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Zapytanie o liczbę elementów drzewa

Biorąc pod uwagę te ograniczenia, nie ma mowy. W takim przypadku albo odzyskasz wszystkie drzewo i zbuduj stronę klienta „wzgórza” lub wykonaj zapytania rekurencyjne, cokolwiek byłoby najbardziej wydajne w konkretnym przypadku.

Z dodatkowym ograniczeniem mania stałej liczby poziomów hierarchii , możesz to zrobić za pomocą wielokrotnego POŁĄCZENIA.

W ogólnym przypadku istnieje kilka modyfikacji konstrukcji, które umożliwiają pokonanie tych ograniczeń. W praktyce łagodzisz ograniczenie „TO JEST moja struktura tabeli”, pozwalając na dodanie dodatkowych pól.

Na przykład możesz uzupełnić strukturę węzłów o left_id i upewnij się, że wszystkie identyfikatory węzłów są w kolejności, gdy odwiedzasz drzewo w pierwszej kolejności:

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

W tym przypadku węzeł 3 przechowuje wartość „5”, węzeł 6 przechowuje wartość „7”, a węzeł 2 również przechowuje wartość „7”. Każdy węzeł przechowuje w LeftID maksimum między identyfikatorami LeftID swoich dzieci a własnym identyfikatorem .

Tak więc węzły bezdzietne mają LeftID równe ich identyfikatorom. Węzeł 1 będzie miał LeftID 7, ponieważ jest to LeftID 2, które otrzymało go z 6.

W tej sytuacji liczenie węzły jest łatwe, jeśli w sekwencji nie ma dziur; wszyscy potomkowie węzła to te węzły, których ID znajduje się pomiędzy ID węzła początkowego a jego LeftID; a liście są identyfikowane przez LeftID równe ID.

Tak więc „wszystkie liście opadające od węzła o identyfikatorze 17” byłyby

SELECT dziecko.*FROM tabela AS parentJOIN tabela AS childON (child.id> parent.id AND child.id <=parent.leftid ) /* Potomek /WHERE child.id =child.leftid / Liść /ORAZ parent.id =17; / Rodzic ma 17 lat

Ta struktura jest niewygodna w utrzymaniu, jeśli chcesz mieć możliwość wykonywania operacji prune i branch, ponieważ musisz przenumerować wszystkie węzły między punktem prune a punktem branch, a także przeniesione węzły.

Inną możliwością, jeśli interesuje Cię tylko liczenie, jest prowadzenie licznika dzieci. Można to utrzymać, aktualizując go iteracyjnie, wybierając wszystkie liście i ustawiając ich licznik na 0 (liście identyfikuje się poprzez LEFT JOIN); następnie wszyscy rodzice z licznikami NULL, którzy mają dzieci z licznikami innymi niż NULL, aktualizując ich liczniki do SUM() liczników dzieci plus COUNT() samych dzieci; i kontynuuj, aż liczba zaktualizowanych wierszy osiągnie zero, ponieważ wszystkie węzły mają liczniki inne niż NULL. Po przycinaniu i rozgałęzianiu po prostu ustawiasz wszystkie liczniki na NULL i powtarzasz.

To ostatnie podejście kosztuje refleksyjne połączenie dla każdego poziomu hierarchii.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Zapytanie MySQL na dwóch różnych polach

  2. MySQL SUM() podając nieprawidłową sumę

  3. Zamień wartości klucza podstawowego MySQL

  4. Zachowanie MySQL GROUP BY

  5. Jak napisać zapytanie MySQL, które zwraca tymczasową kolumnę zawierającą flagi określające, czy element powiązany z tym wierszem istnieje w innej tabeli