2016-06-28 4 views
1

У меня есть три таблицы SQL Server: Projects, ProjectTree, ProjectTreeRec.Рекурсия в операторе Select для SQL Server

Projects аналогичны каталогам, и я пытаюсь найти все подкаталоги под каталогом под названием Standard Parts. Ясно, что здесь требуется рекурсия.

Projects Таблица содержит следующие столбцы:

ProjectID, Name, Deleted 

Таблица ProjectTree имеет следующие столбцы:

ProjectID, ChildProject 

Я не верю, что мне нужно ProjectTreeRec стол в рамках этих усилий, но содержит колонки ChildProjectID, ParentProjectID, Level.

Я хотел бы разработать рекурсивный оператор выбора, чтобы найти все подкаталоги под каталогом Standard Parts, которые не были удалены (не 1, а 0).

Я новичок в CTE и рекурсии. Я получаю некоторые результаты, но не то, что мне нужно.

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

SELECT 
    '(Directory Not Available)' 

UNION 

SELECT DISTINCT 
    C.[Name] 
FROM 
    [EPDM].[dbo].[Projects] A 
JOIN 
    [EPDM].[dbo].[ProjectTree] B ON B.ProjectID = A.ProjectID 
JOIN 
    [EPDM].[dbo].[Projects] C ON B.childproject = C.projectid 
WHERE 
    A.name = 'Standard Part Library' 
    AND A.[Deleted] = 0; 

Любая помощь приветствуется.

+0

Какая версия сервера SQL вы используете? –

+0

Вы можете проверить его на рекурсивный CTE: http://stackoverflow.com/questions/37973842/get-all-duplicate-data-by-parent-or-child-id-sql-server/37975448#37975448 –

+0

Я использую SQL Server Standard 2014. – CodeWriter

ответ

0

Я хотел бы попробовать что-то вроде следующего, чтобы оценить структуру дерева, а затем присоединиться к КТР к вашим таблицам, чтобы получить имена:

DECLARE @SearchProjectID int = 1; 

WITH cteTree AS(
SELECT ProjectID, ChildProject 
    FROM ProjectTree 
    WHERE ProjectID = @SearchProjectID 
UNION ALL 
SELECT pt.ProjectID, pt.ChildProject 
    FROM ProjectTree AS pt 
    JOIN cteTree AS ct ON ct.ChildProject = pt.ProjectID 
) 
SELECT * 
    FROM cteTree 
0

Пожалуйста, попробуйте это ...

CREATE TABLE #Project 
 
(
 
ProjectID INT 
 
,Name varchar(50) 
 
,Deleted bit 
 
) 
 

 
CREATE TABLE #ProjectTree 
 
(
 
ProjectID INT, 
 
ChildProject INT 
 
) 
 

 
INSERT INTO #Project 
 
(ProjectID,Name,Deleted) 
 
SELECT 1,'Standard Part Library',0 
 
UNION ALL SELECT 2,'P2',1 
 
UNION ALL SELECT 3,'P3',0 
 
UNION ALL SELECT 4,'P4',0 
 

 
INSERT INTO #ProjectTree 
 
(ProjectID,ChildProject) 
 
SELECT 1,3 
 
UNION SELECT 2,4 
 

 
SELECT * FROM #Project 
 
SELECT * FROM #ProjectTree 
 

 
;WITH CTE_Project 
 
AS 
 
(
 
SELECT 
 
\t A.ProjectId 
 
\t ,B.ChildProject 
 
\t ,A.Name AS ProjectName 
 
FROM #Project A 
 
\t INNER JOIN #ProjectTree B 
 
\t \t ON A.ProjectId = B.ProjectId 
 
WHERE 
 
\t A.Name = 'Standard Part Library' 
 
\t AND A.[Deleted] = 0 
 

 
UNION ALL 
 

 
SELECT 
 
\t PT.ProjectID 
 
\t ,PT.ChildProject 
 
\t ,CP.ProjectName AS ProjectName 
 
FROM 
 
\t #ProjectTree AS PT 
 
\t INNER JOIN CTE_Project CP 
 
\t \t ON PT.ChildProject = CP.ProjectID 
 
) 
 
SELECT 
 
ProjectName 
 
,ProjectId 
 
,ChildProject 
 
FROM 
 
CTE_Project;

+0

Это выполняется, но не возвращает каталоги ниже Стандартные детали - P2, P3, P4. Закрыть, но не совсем. – CodeWriter

Смежные вопросы