PDA

Просмотр полной версии : Как это можно написать в виде запроса?


Khamza Davletov
28.04.2009, 12:33
Скажем есть таблица, MenuItem

MenuItem
---------
Id int primary key
Name ntext
ParentId int (foreign key на саму себя)
Depth int (глубина вложенности)

в качестве входного параметра задается число :id. Надо вывести весь список имен (Name) записей по иерархии вверх для данного :id в качестве первичного ключа.


Например,

Id | Name | ParentId | Depth
1 | Test1 | NULL | 0
2 | Test21| 1 | 1|
3 | Test31 | 2 | 2
4 | Test22 | 1 | 1


Для 1, это будет "test1",
Для 3, это будет "Test31, Test21, Test1",
Для 4, "Test22, Test1".

Vitaliy Fioktistov
28.04.2009, 13:13
Иерархические (рекурсивные) запросы (http://habrahabr.ru/blogs/sql/43955/)

Timur Naimov
28.04.2009, 13:13
Скажем есть таблица, MenuItem


В лоб - не пытался оптимизировать, возможно есть более рациональное решение


GO

DECLARE @temp TABLE
(
Id INT NOT NULL
)

DECLARE @MenuItemId int, @CurrentParentId int, @CurrentId int

SET @MenuItemId = 3

SELECT @CurrentId = Id, @CurrentParentId = ParentId FROM MenuItems WHERE Id = @MenuItemId
INSERT INTO @temp VALUES(@CurrentId)

WHILE @CurrentParentId IS NOT NULL
BEGIN
SELECT @CurrentId = Id, @CurrentParentId = ParentId FROM MenuItems WHERE Id = @CurrentParentId
INSERT INTO @temp VALUES(@CurrentId)
END
SELECT @CurrentId = Id FROM MenuItems WHERE Id = @CurrentParentId
INSERT INTO @temp VALUES(@CurrentId)

SELECT * FROM MenuItems WHERE Id IN (SELECT Id FROM @temp)

GO

Georgick
28.04.2009, 13:19
этот тип задач называется Nested Sets
погуглите, на эту тему много, что написано

Nestik
29.04.2009, 10:46
Скажем есть таблица, MenuItem

MenuItem
---------
Id int primary key
Name ntext
ParentId int (foreign key на саму себя)
Depth int (глубина вложенности)

в качестве входного параметра задается число :id. Надо вывести весь список имен (Name) записей по иерархии вверх для данного :id в качестве первичного ключа.


Например,

Id | Name | ParentId | Depth
1 | Test1 | NULL | 0
2 | Test21| 1 | 1|
3 | Test31 | 2 | 2
4 | Test22 | 1 | 1


Для 1, это будет "test1",
Для 3, это будет "Test31, Test21, Test1",
Для 4, "Test22, Test1".

Если бд Oracle то

SELECT DECODE(level, 1, '', 2 , '- ', 3, '--', 4, '---')||name
FROM MenuItem
START WITH id = 1
CONNECT BY PRIOR id = parent_id

Khamza Davletov
29.04.2009, 11:12
Если бд Oracle то SELECT DECODE(level, 1, '', 2 , '- ', 3, '--', 4, '---')||name FROM MenuItem START WITH id = 1 CONNECT BY PRIOR id = parent_id

Неа, надо на T-SQL, ну то что comes with MS SQL Server.

stbd
29.04.2009, 11:25
SELECT DECODE(level, 1, '', 2 , '- ', 3, '--', 4, '---')||name
FROM MenuItem
START WITH id = 1
CONNECT BY PRIOR id = parent_id
а если level>4? :)


Неа, надо на T-SQL, ну то что come with MS SQL Server.

в MS SQL, насколько помню, есть common table expressions (CTE), с их помощью делаются рекурсивные запросы

Nestik
29.04.2009, 12:44
а если level>4? Это просто для примера.