web-dev-qa-db-fra.com

SQL Server CTE FOOT DE TOP RÉSUIVE AVEC LA CLAUSE

J'ai une table d'employé avec un champ employé, managers et un domaine de nom.

L'objectif est de faire une récursive avec la récupération de toutes les lignes d'un employé au gestionnaire supérieur (gestionnaireId est NULL).

J'ai trouvé ce lien qui a aidé à obtenir la base du code mais je ne parviens pas à le faire fonctionner pour mon cas

DECLARE @EmployeeTable table ([EmployeeId] int, [name] varchar(10), [managerId] int)
INSERT @EmployeeTable VALUES (1,'Jerome', NULL )  -- tree is as follows:
INSERT @EmployeeTable VALUES (2,'Joe'   ,1)     --                      1-Jerome
INSERT @EmployeeTable VALUES (3,'Paul'  ,2)     --                     /        \
INSERT @EmployeeTable VALUES (4,'Jack'  ,3)     --              2-Joe               9-Bill
INSERT @EmployeeTable VALUES (5,'Daniel',3)     --            /       \                  \
INSERT @EmployeeTable VALUES (6,'David' ,2)     --     3-Paul          6-David       10-Sam
INSERT @EmployeeTable VALUES (7,'Ian'   ,6)     --    /      \            /    \
INSERT @EmployeeTable VALUES (8,'Helen' ,6)     -- 4-Jack  5-Daniel   7-Ian    8-Helen
INSERT @EmployeeTable VALUES (9,'Bill ' ,1)     --
INSERT @EmployeeTable VALUES (10,'Sam'  ,9)     --

DECLARE @employeeId int = 3

;WITH StaffTree AS
(
    SELECT 
        c.[EmployeeId], c.[name], c.managerId, 0 AS [Level]
        FROM @EmployeeTable c
        LEFT OUTER JOIN @EmployeeTable  cc ON c.managerId=cc.EmployeeId
        WHERE c.EmployeeId=@employeeId OR (@employeeId IS NULL AND     c.managerId IS NULL)
    UNION ALL
        SELECT 
            s.[EmployeeId], s.[name], s.managerId, t.[Level]+1
        FROM StaffTree t
            INNER JOIN @EmployeeTable s ON t.[EmployeeId]=s.managerId
        WHERE s.managerId=@employeeId OR @employeeId IS NULL OR t.Level>1
)
SELECT * FROM StaffTree

Si vous sélectionnez la hiérarchie de l'employé 3, le résultat devrait être:

EmployeeId | Name    | ManagerId 
1          | Jerome  | NULL
2          | Joe     | 1
3          | Paul    | 2
3
Lenny32

Échanger les colonnes dans la jointure interne de la partie récursive est un moyen d'y aller.

Rejoindre des colonnes passées de t.[EmployeeId]=s.managerId à s.[EmployeeId]=t.managerId

J'ai supprimé certaines parties qui ne semblaient pas être nécessaires.

DECLARE @employeeId int = 3

;WITH StaffTree AS
(
    SELECT 
        c.[EmployeeId], c.[name], c.managerId, 0 AS [Level]
        FROM @EmployeeTable c
        WHERE c.EmployeeId=@employeeId OR (@employeeId IS NULL AND     c.managerId IS NULL)
    UNION ALL
        SELECT 
            s.[EmployeeId], s.[name], s.managerId, t.[Level]+1
        FROM StaffTree t
        INNER JOIN @EmployeeTable s ON s.[EmployeeId]=t.managerId
)
SELECT EmployeeId,
       name,
       managerId 
FROM StaffTree
ORDER BY managerId asc;

résultat

EmployeeId  name    managerId
1           Jerome  NULL
2           Joe     1
3           Paul    2
2
Randi Vertongen

On dirait que vous avez eu une petite erreur lors de la copie de l'exemple que vous avez lié à -

c.[EmployeeId], c.[name], c.managerId, 0 AS [Level]

devrait être

c.[EmployeeId], c.[name], c.managerId, 1 AS [Level]

Une fois que je fais ce changement, votre code fonctionne de la même manière que l'exemple.

0
Darren G

Ce lien vous aidera beaucoup à apprendre des CTES récursifs avec des exemples excellents et utiles: https://www.codeproject.com/articles/818694/sql-queries-a-manage-hierarchical-orent-child .

0
Pantea