This is the original blogger: PracticalSQLDba
First of all let us create a table called Employee table using the below script.
CREATE TABLE Employee
(Employee_id INT PRIMARY KEY,
EmployeeName VARCHAR(100),
Manager_id INT
)
Let us populate the sample data.
INSERT INTO Employee VALUES (1,'A',NULL)INSERT INTO Employee VALUES (2,'A_B',1)INSERT INTO Employee VALUES (3,'A_C',1)INSERT INTO Employee VALUES (4,'A_D',1)
INSERT INTO Employee VALUES (5,'B_B',2)INSERT INTO Employee VALUES (6,'B_C',2)
INSERT INTO Employee VALUES (7,'C_B',3)INSERT INTO Employee VALUES (8,'C_C',3)
INSERT INTO Employee VALUES (9,'BB_B',5)INSERT INTO Employee VALUES (10,'BB_C',5)
INSERT INTO Employee VALUES (11,'BC_B',6)INSERT INTO Employee VALUES (12,'BC_C',6)
INSERT INTO Employee VALUES (13,'BBB_B',9)INSERT INTO Employee VALUES (14,'BBC_B',10)
I have used separate insert statement for better readability.
Here Manager_id is a foreign key referring to Employee_id. Let us assume that we need to generate an employee reports with Employee_id,Employee Name ,Manager_id,Manager Name and hierarchical position (level) of employee in the organization. This can be implemented very easily using recursive CTE which introduced in SQL server 2005.Below script will give the result.
;WITH DirectReports(Manager_ID, ManagerName,Employee_ID, EmployeeName ,EmployeeLevel)AS (
--Select the root or parent records
SELECT Manager_ID, CAST('' AS VARCHAR(100))AS ManagerName, Employee_ID, EmployeeName, 0 AS EmployeeLevel
FROM Employee
WHERE Manager_ID IS NULL
UNION ALL
--Recursive part :Select the child
SELECT e.Manager_ID, m.EmployeeName AS ManagerName, e.Employee_ID, e.EmployeeName, EmployeeLevel + 1
FROM Employee e
INNER JOIN DirectReports d
ON e.Manager_ID = d.Employee_ID
INNER JOIN employee m ON e.manager_ID = m.employee_id
)
SELECT * FROM DirectReports ;
Let us see how we can write the same with out CTE, which will help us to visualize the recursive CTE.
DECLARE @DirectReports AS TABLE
(Manager_ID INT,
ManagerName VARCHAR(100),
Employee_ID INT,
EmployeeName VARCHAR(100) ,
EmployeeLevel INT)--Selecting the 0th level (who do not have manager) employeeINSERT INTO @DirectReports
SELECT Manager_ID,
CAST('' AS VARCHAR(100))AS ManagerName,
Employee_ID, EmployeeName ,
0 AS EmployeeLevel
FROM Employee
WHERE Manager_ID IS NULL DECLARE @Recursion INT =0
WHILE(@@ROWCOUNT>0)BEGIN
SET @Recursion =@Recursion +1
INSERT INTO @DirectReports
SELECT
e.Manager_ID,
m.EmployeeName AS ManagerName,
e.Employee_ID,
e.EmployeeName ,
@Recursion
FROM Employee e
INNER JOIN @DirectReports d
ON e.Manager_ID = d.Employee_ID
INNER JOIN employee m ON e.manager_ID = m.employee_id
WHERE d.EmployeeLevel=@Recursion -1 --to select only the last execution result
END
SELECT * FROM @DirectReports
No comments:
Post a Comment