Как получить все дочерние узлы в древовидной структуре?Запрос SQL? - PullRequest
6 голосов
/ 08 июня 2011

таблица - пользователь

столбцы - (userId, name, managerId)

строк -

(1,nilesh,0)
(2,nikhil,1)    
(3,nitin ,2)  
(4,Ruchi,2)

если я предоставлю идентификатор пользователя, он должен перечислить всех сообщающих людейДля него .если я задаю userId = 2, он должен вернуть 3,4.

Верен ли этот запрос

SELECT ad3.userId
FROM user au , user  au2 , user  au3
WHERE 
    ad.managerId = ad2.managerId AND 
    ad3.managerId = ad2.userId AND
    ad.userId=2

Существует ли эффективный способ управления древовидной структурой в БД?Как насчет правого и левого листового пути?

Ответы [ 4 ]

13 голосов
/ 08 июня 2011

Я использую текстовое поле для работы с деревьями в SQL. Это проще, чем использовать левые / правые значения.

Давайте возьмем пример из статьи MySQL:

+-----------------------+
| name                  |
+-----------------------+
| ELECTRONICS           |
|  TELEVISIONS          |
|   TUBE                |
|   LCD                 |
|   PLASMA              |
|  GAME CONSOLES        |
|  PORTABLE ELECTRONICS |
|   MP3 PLAYERS         |
|    FLASH              |
|   CD PLAYERS          |
|   2 WAY RADIOS        |
|    FRS                |
+-----------------------+

В результате получится таблица, подобная этой:

Id      ParentId        Lineage     Name

1       null            /1/         ELECTRONICS
2       1               /1/2/       TELEVISIONS
3       2               /1/2/3/     TUBE
4       2               /1/2/4/     LCD
5       2               /1/2/5/     PLASMA
6       6               /1/6/       GAME CONSOLES
7       1               /1/7/       PORTABLE ELECTRONICS
8       7               /1/7/8/     MP3 PLAYERS
9       8               /1/7/8/9/   FLASH
10      7               /1/7/10/    CD PLAYERS
11      1               /1/11/      2 WAY RADIOS
12      11              /1/11/12/   FRS

Найдите все портативные устройства, которые вы просто используете Lineage с портативных компьютеров:

SELECT * FROM theTable WHERE Lineage LIKE '/1/7/%'

Минусы:

  • Вам нужно делать ОБНОВЛЕНИЕ после каждой ВСТАВКИ, чтобы добавить PK в Lineage

Предложение:

Обычно я добавляю другой столбец, в который я помещаю путь в виде текста (например, 'electronics/televisions/tube')

9 голосов
/ 08 июня 2011

Примерно так (ANSI SQL):

WITH RECURSIVE emptree (userid, name, managerid) AS (
    SELECT userid, 
           name, 
           managerid
    FROM the_table 
    WHERE userid = 2

    UNION ALL

    SELECT c.userid, 
           c.name,
           c.managerid
    FROM the_table c
       JOIN emptree p ON p.userid = c.managerid
)
SELECT *
FROM emptree
9 голосов
/ 08 июня 2011

По моему мнению, проблема с моделью списка смежности заключается в том, что с ней становится трудно иметь дело с SQL, особенно если вы не знаете, насколько глубоко будет вложена ваша древовидная структура.

The 'путь влево и вправо - вы упомянули, вероятно, модель вложенного множества и позволяет вам хранить такие вещи, как

LFT   RGT   Name
1     8      nilesh
2     7      nikhil
3     4      nitin
5     6      Ruchi

Тогда вы можете найти всех подчиненных, просто

SELECT Name FROM Hierarchy WHERE LFT BETWEEN @LFT AND @RGT

Я думаю, что гораздо проще иметь дело с запросами, но труднее сделать для модификаций дерева.Если ваши данные не сильно меняются, то я думаю, что это гораздо лучшее решение.(Однако не все согласятся со мной)

Здесь есть Очень хорошее руководство

0 голосов
/ 08 июня 2011
SELECT user.id FROM user WHERE user.managerid = 2

Это то, что вы хотите?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...