sql выбрать записи из заданного поддерева

Selena

Есть табличка: ID, PARENT_ID, NAME.
Нужно выбрать записи из заданного поддерева.
Я так понимаю на чистом SQL этого не сделать?

VitMix

Если дерево невысокое, то можно сделать серию запросов по уровням. Типа

SELECT id, name FROM tbl WHERE parent = 666;
SELECT a.id, a.name FROM tbl AS a, tbl AS b WHERE a.parent = b.id AND b.parent = 666;
SELECT a.id, a.name FROM tbl AS a, tbl AS b, tbl AS c WHERE a.parent = b.id AND b.parent = c.id AND c.parent = 666;


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

Selena

это понятно,
но всеравно спасибо.

rfgbnfy

Рекрусию на "голом" SQL вроде как организовать нельзя . По крайней мере я с таким не сталкивася и не представляю как это сделать ................

eduard615

по человечески организовать дерево, например, правильно присваивая id.

Dasar

Смотря что понимать под чистым sql-ем....
ps
AFAIK, в stored procedure-ах можно и циклы использовать.

Selena

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

ranet

По своему вопросу можешь почитать
Guru’s Guide to Transact-SQL
главу 12. Нierachies
пример решения твоей задачи на TSQL:
SET NOCOUNT ON
CREATE TABLE staff (employee int PRIMARY KEY, employee_name varchar(10 supervisor int NULL REFERENCES staff (employee
INSERT staff VALUES (1,'GROUCHO',1)
INSERT staff VALUES (2,'CHICO',1)
INSERT staff VALUES (3,'HARPO',2)
INSERT staff VALUES (4,'ZEPPO',2)
INSERT staff VALUES (5,'MOE',1)
INSERT staff VALUES (6,'LARRY',5)
INSERT staff VALUES (7,'CURLY',5)
INSERT staff VALUES (8,'SHEMP',5)
INSERT staff VALUES (9,'JOE',8)
INSERT staff VALUES (10,'CURLY JOE',9)
SELECT chartdepth=1, employee=o2.employee, supervisor=o1.employee
INTO #org_chart
FROM staff o1 INNER JOIN staff o2 ON (o1.employee=o2.supervisor)
WHILE (@@rowcount > 0) BEGIN
INSERT #org_chart (chartdepth, employee, supervisor)
SELECT DISTINCT o1.chartdepth+1, o2.employee, o1.supervisor
FROM #org_chart o1 INNER JOIN #org_chart o2 ON (o1.employee=o2.supervisor)
WHERE o1.chartdepth=(SELECT MAX(chartdepth) FROM #org_chart)
AND o1.supervisor<>o1.employee
END
SELECT s.employee_name, supervises='supervises', e.employee_name
FROM #org_chart o INNER JOIN staff s ON (o.supervisor=s.employee)
INNER JOIN staff e ON (o.employee=e.employee)
WHERE o.supervisor<>o.employee
GROUP BY o.supervisor, o.employee, s.employee_name, e.employee_name
ORDER BY o.supervisor, o.employee, s.employee_name, e.employee_name
GO
DROP TABLE staff, #org_chart

laisan

А что за СУБД? Если Oracle, то там есть конструкция
select
connect by prior
start with
которая позволяет делать иерархические запросы

donniebrasco

соори за оффтоп и флуд:
ехал в метро сегодня и там чел держал распечатку именно этой таблицы... если это было действительно: отклинись!

Selena

красиво

Selena

не, не Oracle. InterBase(Firebird)
Оставить комментарий
Имя или ник:
Комментарий: