问题
I have a emp table,
CREATE TABLE [dbo].[Emp](
[EmpId] [int] NULL,
[EmpName] [nvarchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[ManagerId] [int] NULL
) ON [PRIMARY]
Now, insert below values into the table
Insert Into Emp Values(1,'A',0)
Insert Into Emp Values(2,'B',1)
Insert Into Emp Values(3,'C',2)
Insert Into Emp Values(4,'D',2)
Insert Into Emp Values(5,'E',4)
Insert Into Emp Values(6,'F',4)
Insert Into Emp Values(7,'G',4)
Insert Into Emp Values(8,'H',6)
Insert Into Emp Values(9,'I',5)
Insert Into Emp Values(10,'J',7)
Insert Into Emp Values(11,'K',4)
I want to list employee name and their manager name in select statement.
What I am doing now is creating a temporary table which has all manager name and their Id.
Then getting the name from the manager table based on Id.
But I know this is not a correct way, in fact it is complex.
回答1:
You should use a recursive CTE (Common Table Expression) for this:
-- define the recursive CTE and give it a name
;WITH Hierarchy AS
(
-- "anchor" - top-level rows to select, here those with ManagerId = 0
SELECT EmpId, EmpName, NULL AS 'MgrId', CAST(NULL AS NVARCHAR(50)) AS 'MgrName', 1 AS 'Level'
FROM dbo.Emp
WHERE ManagerId = 0
UNION ALL
-- recursive part - join an employee to its manager via ManagerId -> mgr.EmpId
SELECT e.EmpId, e.EmpName, mgr.EmpId, mgr.EmpName, mgr.Level + 1 AS 'Level'
FROM dbo.Emp e
INNER JOIN Hierarchy mgr ON e.ManagerId = mgr.EmpId
)
SELECT * FROM Hierarchy
回答2:
You are correct: you don't have to use a temporary table just for this. Try using recursive queries. Take a look at this link on MSDN. There is an example with ManagerId/EmployeeID. Just as in your query.
来源:https://stackoverflow.com/questions/8111771/select-parent-and-child-from-the-same-table