SQL: рекурсивный путь - PullRequest
       9

SQL: рекурсивный путь

3 голосов
/ 29 апреля 2010

Можно ли создать "преобразователь дерева" в SQL?

У меня есть таблица:

ID Name Parent
1  a
2  b    1
3  c    1
4  d    3

Теперь я хочу запрос SQL, который возвращает:

ID   PATH
1    /a
2    /a/b
3    /a/c
4    /a/c/d

Возможно ли это с SQL? Это облегчит мне многое. Любая помощь будет принята с благодарностью!

Ответы [ 5 ]

5 голосов
/ 07 января 2011

Используя CTE в SQL Server 2005 и более поздних версиях, вот фрагмент, который я должен сделать:

WITH Paths([Level], [FullPath], [ID]) AS 
(
    SELECT 
        0 AS [Level], 
        Name AS FullPath, 
        ID
    FROM dbo.Entity
    WHERE (ParentEntityID IS NULL)

    UNION ALL

    SELECT 
        p.[Level] + 1 AS [Level], 
        CASE RIGHT(p.[FullPath], 1) 
        WHEN '\' THEN p.[FullPath] + c.[Name] 
        ELSE p.[FullPath] + '\' + c.[Name] 
    END AS FullPath, 
    c.ID
    FROM dbo.Entity AS c 
    INNER JOIN Paths AS p ON p.ID = c.ParentEntityID
)
SELECT [FullPath], [ID]
FROM Paths
1 голос
/ 29 апреля 2010

В зависимости от того, какой сервер базы данных используется, эта функция может быть уже предоставлена ​​вам. В противном случае вы можете создать функцию, которая сама будет вызывать эту информацию, или реализовать решение Materialized Path .

Обновление:

Для DB2 вы можете использовать Рекурсивные выражения общих таблиц .

1 голос
/ 29 апреля 2010

Существует несколько различных способов представления дерева в базе данных SQL. Я думаю, я не знаю много, но я знаю, что Django Treebeard использует 3 различных способа сделать это. Если вы посмотрите на документацию, в ней есть краткие описания всех способов:

список смежностей - что вы уже делаете

материализованный путь - статья: http://www.dba -oracle.com / t_sql_patterns_trees.htm

вложенные множества - о, вот википедия: http://en.wikipedia.org/wiki/Nested_set_model

1 голос
/ 29 апреля 2010

Да, смотрите здесь . Вы можете использовать операторы «начать с» и «соединять по предыдущим», я использовал это в прошлом для создания панировочных сухарей в веб-приложении.

0 голосов
/ 07 сентября 2012

Предположим, у нас есть простая таблица DLFolder со следующими столбцами:

| folderId | name | parentFolderId |

В Oracle вы можете использовать операцию sys_connect_by_path.

select fo.folderId as folder_id, sys_connect_by_path(fo.name, '/') as relname
from DLFolder fo
start with fo.parentFolderId=0
connect by prior fo.folderId = fo.parentFolderId

даст следующий результат:

/1020_Training_Material
/1020_Training_Material/2000_IBBA
/1020_Training_Material/2000_IBBA/5000_FR
/1020_Training_Material/2000_IBBA/5050_NL

См. http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions164.htm

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