powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Еще раз о деревьях (вложенные множества)
6 сообщений из 6, страница 1 из 1
Еще раз о деревьях (вложенные множества)
    #32028526
Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Начитался я статей по поводу представления иерархических структур в SQL.
Попробовал использовать метод вложенных множеств как рекомендуют, вроде
все класно, только что-то не пойму как состряпать такой простой запрос:
Есть у меня таблица (ID int, Lft int, Rgt int), нужно получить
для каждого ID его непосредственного bossa (ParentID). Кто-нибудь
может подсказать?
...
Рейтинг: 0 / 0
Еще раз о деревьях (вложенные множества)
    #32028536
skif
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
немного непонятно в вопросе: Lft значит Left, Rgt значит Right, видимо? И кто из них куда смотрит? Если Left смотрит на родителя, то Right куда? На детей? Тогда он явно лишний просто в этой ситуации.

Я буквально позавчера читал MSDN, там есть две конкретные статьи (видимо, MS тоже достали такими вопросами
). Статьи называются как то так
Extending Hierarhies и Extending Networks. Могу ошибиться - не Extending, а Expanding, скорее всего. Но именно два слова. Там конкретные реализации обоих алгоритмов - когда иерархия, то значит, что элемент может быть только наследником от одного родителя. Networks - это когда бардак
, когда элемент может быть наследником любого количества "отцов". Там все разжевано.
...
Рейтинг: 0 / 0
Еще раз о деревьях (вложенные множества)
    #32028555
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пример из статьи http://www.sdm.viptop.ru/articles/sqltrees.html

Список ВСЕХ боссов для выбранного ID

SELECT @ID, B1.ID, (B1.Rgt - B1.Lft) AS height
FROM Personnel B1, Personnel E1
WHERE E1.Lft BETWEEN B1.Lft AND B1.Rgt
AND E1.Rgt BETWEEN B1.Lft AND B1.Rgt
AND E1.ID = @ID

Непосредственным боссом будет тот, у которого значение height - наименьшее. Ну или наибольшее значение Lft или наименьшее значение Rgt. Поскольку значения Lft и Rgt также уникальны как и ID, то можно определить непосредственного босса так:

SELECT MAX(B1.Lft) AS BossLft
FROM Personnel B1, Personnel E1
WHERE E1.Lft BETWEEN B1.Lft AND B1.Rgt
AND E1.Rgt BETWEEN B1.Lft AND B1.Rgt
AND E1.ID = @ID

Ну, и по значению BossLft однозначно определить ID непосредственного босса
...
Рейтинг: 0 / 0
Еще раз о деревьях (вложенные множества)
    #32028590
une_femme
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
CREATE TABLE Employees
(empid int NOT NULL,
mgrid int NULL,
empname varchar(25) NOT NULL,
salary money NOT NULL,
lvl int NULL,
hierarchy varchar(900) NULL,
CONSTRAINT PK_Employees_empid PRIMARY KEY(empid),
CONSTRAINT FK_Employees_mgrid_empid
FOREIGN KEY(mgrid)
REFERENCES Employees(empid))
GO


для каждого employee ID - его непосредственного bossa :

SELECT E.empname AS EmployeeName, M.empname AS ManagerName
FROM Employees AS E
LEFT OUTER JOIN Employees AS M
ON E.mgrid = M.empid




http://www.osp.ru/win2000/sql/967.htm

ochen" xoroshaia stat"ia (" Иерархические структуры, не требующие сопровождения ")
...
Рейтинг: 0 / 0
Еще раз о деревьях (вложенные множества)
    #32028640
Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
То ВладимирМ: Ваш пример не работает (BossLft получается = Lft для @ID).
Пример из статьи я смотрел, все получается как надо. Просто у меня не
получается доработать данный пример так, что бы получить ближайшего bossa
для каждого ID таблицы, а не для конкретного @ID
т.е. из таблицы вложенных множеств
ID LFT RGT
-----------------
1 1 10
2 2 5
3 3 4
4 6 9
5 7 8

получить таблицу смежных вершин графа
ID ParentID
------------------
1 NULL
2 1
3 2
4 1
5 4
...
Рейтинг: 0 / 0
Еще раз о деревьях (вложенные множества)
    #32028750
Фотография Александр Степанов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
\nSelect
step1.ID As ID,
step2.ID As Parent
From
(
SELECT
EH1.ID,MAX(EH2.Lft) As lft
FROM
Hierarchy AS EH1
LEFT join Hierarchy AS EH2
on EH1.lft > EH2.lft
AND EH1.lft < EH2.rgt
Group By
EH1.ID
) step1
left join Hierarchy step2
on step2.Lft=step1.lft
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Еще раз о деревьях (вложенные множества)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]