CTE для создания дерева объектов

У меня есть две таблицы: Папка, Файлы. Каждая таблица имеет 4 поля: ParentID, ID, Name, Type

Мне нужно создать CTE, чтобы получить все дерево за один раз, используя T-SQL. Пока это то, что я сделал, но рекурсия еще не активна.

Я забыл упомянуть, что внутри папки может быть одна или несколько папок/файлов.


person Raffaeu    schedule 20.06.2012    source источник
comment
Как файлы относятся к папкам? И каков ожидаемый результат (формат) дерева?   -  person Lucero    schedule 20.06.2012
comment
Всегда используйте ParentID. Обе таблицы имеют поле ParentID, которое указывает на поле Folder.ID.   -  person Raffaeu    schedule 20.06.2012


Ответы (1)


Предполагая, что вы используете NULL для элементов ParentID в корне, должно работать следующее:

WITH FilesAndFolders AS (
    SELECT ID AS FileID, 
           CAST(NULL AS int) AS FolderID, 
           ParentID, 
           Name, 
           [Type]
    FROM File
    UNION ALL
    SELECT CAST(NULL AS int),
           ID, 
           ParentID, 
           Name, 
           [Type]
    FROM Folder
),
Tree AS (
    SELECT FileID, 
           FolderID, 
           Name, 
           [Type], 
           CAST('' AS nvarchar(MAX)) AS [Path]
    FROM FilesAndFolders
    WHERE ParentID IS NULL
    UNION ALL 
    SELECT FF.FileID, 
           FF.FolderID, 
           FF.Name, 
           FF.[Type], 
           T.[Path]+T.[Name]+'/'
    FROM FilesAndFolders FF
    JOIN Tree T ON T.FolderID = FF.ParentID
)
SELECT FileID, FolderID, [Path]+[Name] FullName, [Type]
FROM Tree
person Lucero    schedule 20.06.2012
comment
Это работает, спасибо. Я, вероятно, удалю первый выбор всех и передам parentID внутри первого CTE, чтобы сделать его быстрее. - person Raffaeu; 20.06.2012
comment
@Raffaeu, рад, что это работает. Однако я не понимаю, что вы имеете в виду под удалением первого выбора - с заданной структурой данных (например, файлы и папки в двух разных таблицах вместо одной) я не уверен, как вы хотите значительно ускорить работу. За кулисами рекурсивный CTE на самом деле не является рекурсивным, а скорее имеет вид курсора на созданных строках, которые можно использовать для соединения и, следовательно, добавления дополнительных строк. Кстати: привет из страны, в которой вы работали... ;) - person Lucero; 20.06.2012