uForum.uz

uForum.uz (https://uforum.uz/index.php)
-   ЦППМП (https://uforum.uz/forumdisplay.php?f=222)
-   -   Как это можно написать в виде запроса? (https://uforum.uz/showthread.php?t=8951)

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

Иерархические (рекурсивные) запросы

Timur Naimov 28.04.2009 13:13

Цитата:

Сообщение от Khamza Davletov (Сообщение 210982)
Скажем есть таблица, 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

Цитата:

Сообщение от Khamza Davletov (Сообщение 210982)
Скажем есть таблица, 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

Цитата:

Сообщение от Nestik (Сообщение 211531)
Если бд 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

Цитата:

Сообщение от Nestik (Сообщение 211531)
SELECT DECODE(level, 1, '', 2 , '- ', 3, '--', 4, '---')||name
FROM MenuItem
START WITH id = 1
CONNECT BY PRIOR id = parent_id

а если level>4? :)

Цитата:

Сообщение от Khamza Davletov
Неа, надо на T-SQL, ну то что come with MS SQL Server.

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

Nestik 29.04.2009 12:44

Цитата:

Сообщение от stbd (Сообщение 211550)
а если level>4?

Это просто для примера.


Текущее время: 09:54. Часовой пояс GMT +5.

Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd. Перевод: zCarot
OOO «Единый интегратор UZINFOCOM»