Mysql
 sql >> база данни >  >> RDS >> Mysql

Запитване на брой елементи от дърво

Имайки предвид тези ограничения, няма начин. В такъв случай или ще извлечете всички дървото и изградете „хълм“ клиентска страна или изпълнете рекурсивни заявки, каквото би било най-ефективно в конкретния случай.

С допълнителното ограничение за наличието на фиксиран брой нива на йерархия , можете да направите това с множество JOIN.

В общия случай има няколко структурни модификации, които позволяват преодоляването на тези ограничения. На практика облекчавате ограничението "ТОВА е структурата на моята таблица", което позволява добавяне на допълнителни полета.

Например, можете да допълните структурата на възела с left_id стойност и се уверете, че всички идентификатори на възли са в последователност, когато посетите дървото в дълбочина първо:

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

В този случай възел 3 ще съхрани стойността "5", възел 6 ще съхрани стойността "7", а възел 2 също ще съхрани стойността "7". Всеки възел съхранява в LeftID максимума между левите си идентификатори на децата и собствения си идентификатор .

Така възлите без деца имат LeftID, равен на техните идентификатори. Възел 1 ще има LeftID 7, тъй като това е LeftID от 2, което го получи от 6.

В тази ситуация отброяване възли е лесно, ако няма дупки в последователността; всички потомци на възел са онези възли, чийто идентификатор е между идентификатора на началния възел и неговия ляв идентификатор; и листата се идентифицират като имат LeftID, равен на ID.

Така че "всички листа, слизащи от идентификатор на възел 17" ще бъдат

SELECT child.*FROM table AS parentJOIN таблица AS childON (child.id> parent.id AND child.id <=parent.leftid ) /* Descendant /WHERE child.id =child.leftid / Лист /AND parent.id =17; / Родителят е на 17

Тази структура е неудобна за поддържане, ако искате да можете да правите подрязване и разклоняване, тъй като трябва да преномерирате всички възли между точката на подрязване до точката на разклоняване, както и преместените възли.

Друга възможност, ако се интересувате само от броене, е да запазите детски брояч. Това може да се поддържа, като го актуализирате итеративно, като изберете всички листа и зададете брояча им на 0 (вие идентифицирате листа чрез LEFT JOIN); след това всички онези родители с броячи NULL, които имат деца с броячи без NULL, актуализирайки броячите си до SUM() детски броячи плюс COUNT() на самите деца; и продължава, докато броят на актуализираните редове стане нула, тъй като всички възли имат броячи без NULL. След подрязване и разклоняване просто задавате всички броячи на NULL и повтаряте.

Този последен подход струва отразяващо присъединяване за всяко ниво на йерархия.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MYSQL - Групиране по лимит

  2. Съхраняване на идентификационни данни на MS SQL Server в база данни на MySQL

  3. Как да оптимизираме SQL заявката с изчисляване на разстояние по дължина и ширина?

  4. Вмъкване на MySQL променливи в Google карти с PHP

  5. Изчислете средната стойност, дисперсията и стандартното отклонение на две числа в два различни реда/колони с sql / PHP на конкретни дати