Как получить все дочерние элементы узла в древовидной структуре? SQL-запрос?
таблица - пользователей
столбцы - (userId, name, managerId)
строк -
(1,nilesh,0)
(2,nikhil,1)
(3,nitin ,2)
(4,Ruchi,2)
Если я дам id пользователя, он должен перечислить всех сообщающих ему людей . если я дам 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 ответов
на мой взгляд, проблема с моделью списка смежности заключается в том, что в SQL становится трудно иметь дело, особенно когда вы не знаете, насколько глубоко вложена ваша древовидная структура.
"левый и правый лист", который вы упомянули, вероятно, является вложенной моделью набора и позволяет хранить такие вещи, как это
LFT RGT Name
1 8 nilesh
2 7 nikhil
3 4 nitin
5 6 Ruchi
тогда вы можете найти всех подчиненных anyones просто
SELECT Name FROM Hierarchy WHERE LFT BETWEEN @LFT AND @RGT
Я думаю, что гораздо проще иметь дело с запросами, но сложнее сделать для модификаций дерева. Если ваши данные не сильно меняются, я думаю, что это гораздо лучшее решение. (Не все согласятся со мной, хотя)
Я использую текстовое поле для работы с деревьями в SQL. Это проще, чем использовать значения left/right.
давайте возьмем пример из статьи 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 from portables:
SELECT * FROM theTable WHERE Lineage LIKE '/1/7/%'
плюсы:
- вам нужно сделать обновление после каждой вставки, чтобы добавить ПК к Линии
предложение:
Я обычно добавляю еще один столбец, где я помещаю путь в виде текста (например 'electronics/televisions/tube'
)
что-то вроде этого (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