2016-06-28 16 views
1

Ich habe drei SQL Server-Tabellen: Projects, ProjectTree, ProjectTreeRec.Rekursion in Select-Anweisung für SQL Server

Projects sind analog zu Verzeichnissen und ich versuche, alle Unterverzeichnisse unter einem Verzeichnis namens Standard Parts zu finden. Offensichtlich ist Rekursion hier erforderlich.

Die Projects Tabelle hat die folgenden Spalten:

ProjectID, Name, Deleted 

Die ProjectTree Tabelle hat die folgenden Spalten:

ProjectID, ChildProject 

Ich glaube nicht, ich brauche die ProjectTreeRec Tabelle als Teil dieser Bemühungen, aber es enthält die Spalten ChildProjectID, ParentProjectID, Level.

Ich möchte eine rekursive Select-Anweisung entwickeln, um alle Unterverzeichnisse unterhalb des Verzeichnisses Standard Parts zu finden, die nicht gelöscht wurden (nicht 1, sondern 0).

Ich bin neu in CTE und Rekursion. Ich bekomme ein paar Ergebnisse, aber nicht das, wonach ich suche.

Hier ist der nicht-rekursive Aufruf, der mich die erste Ebene nach unten findet, aber nicht tiefer geht. Es funktioniert gut.

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; 

Jede Hilfe ist willkommen.

+0

Welche Version von SQL Server verwenden Sie? –

+0

Sie können es für rekursive CTE überprüfen: http://stackoverflow.com/questions/37973842/get-all-duplicate-data-by-parent-orchild-id-sql-server/37975448#37975448 –

+0

Ich verwende SQL Server Standard 2014 – CodeWriter

Antwort

0

Ich würde so etwas wie die folgenden versuchen, um die Baumstruktur zu bewerten und dann den CTE auf Ihre Tabellen beitreten, um die Namen zu erhalten:

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

Bitte versuchen Sie diese ...

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

Dies funktioniert, gibt aber die unten angegebenen Verzeichnisse nicht zurück Normteile - P2, P3, P4. Nah aber nicht ganz da. – CodeWriter