2015-04-18 27 views
0

鉴于下面的表格模式,我被问到如何找到安妮的所有下属。递归vs公用表达式 - 何时使用CTE?

----------------------------- 
EmployeeId | Name | ManagerId 
----------------------------- 
1   | Annie| NULL 
2   | Ben | 1 
3   | Carl | 2 
4   | Den | 1 
.... 

从ORM &服务器端背景的人,我会写一个递归FUNC来解决这个问题。但是,我被告知有一种使用CTE的方法。为什么以及何时使用CTE?为什么不递归? CTE比递归更快吗?

不管怎么说,这是我的递归实现:

public class Employee{ 
    int employeeId; 
    string name; 
    public List<Employee> managers {get;set}; 
    public List<Employee> subordinates {get;set}; 
} 

//find direct & non-direct reports 
public List<Employee> getSubordinates(Employee emp) { 
    List<Employee> reports = new List<Employee>(); 
    if (emp.subordinates == null || emp.subordinates.Count == 0) 
     return null; 

    foreach(Employee e in emp.subordinates) { 
     reports.AddRange(getSubordinates(e)); 
    } 

    return reports.DistinctBy(x=>x.employeeId); 
} 
+2

使用'CTE'可以实现在服务器端的递归,从而返回所需的结果与一个单一查询设置。你可以在这里找到很多关于如何做到这一点的例子。 –

回答

0

通用表表达式(CTE的)会帮助你accomplish recursion从数据库端,所以你真的会完成同样的事情,你的方法用的密钥异常是它与通过SQL一个查询完成,例如:

WITH subordinates AS (
    SELECT e.EmployeeId, e.Name 
    FROM dbo.Employee e 
    WHERE e.ManagerId = 1 
    UNION ALL 
    SELECT e.EmployeeId, e.Name 
    FROM dbo.Employee e 
     INNER JOIN subordinates s ON s.EmployeeId = e.ManagerId 
) 
SELECT s.EmployeeId, s.Name 
FROM subordinates s; 

的好处是,它可能更快,因为它是在一个查询正在做VS从递归ORM方法生成多个查询。

T-SQL Fiddle Example