Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 递归与公共表表达式-何时使用CTE?_Sql_Recursion_Common Table Expression_Recursive Query - Fatal编程技术网

Sql 递归与公共表表达式-何时使用CTE?

Sql 递归与公共表表达式-何时使用CTE?,sql,recursion,common-table-expression,recursive-query,Sql,Recursion,Common Table Expression,Recursive Query,根据下表模式,我被问及如何找到Annie的所有下属 ----------------------------- EmployeeId | Name | ManagerId ----------------------------- 1 | Annie| NULL 2 | Ben | 1 3 | Carl | 2 4 | Den | 1 .... 来自ORM和服务器端背景,我将编写一个递归函数来解决这个问题。然而,有人告

根据下表模式,我被问及如何找到Annie的所有下属

-----------------------------
EmployeeId | Name | ManagerId
-----------------------------
1          | Annie| NULL
2          | Ben  | 1
3          | Carl | 2
4          | Den  | 1
....
来自ORM和服务器端背景,我将编写一个递归函数来解决这个问题。然而,有人告诉我,使用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);
}
公共类员工{
国际雇员ID;
字符串名;
公共列表管理器{get;set};
公共列表下属{get;set};
}
//查找直接报告和非直接报告
公开下属名单(员工emp){
列表报告=新列表();
if(emp.substances==null | | emp.substances.Count==0)
返回null;
foreach(emp下属中的员工e){
报告.AddRange(getsubstances(e));
}
返回报告.DistinctBy(x=>x.employeeId);
}
公共表表达式(CTE)将从数据库方面为您提供帮助,因此实际上您将完成与您的方法相同的事情,关键的例外是它是通过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;
好处是它可能更快,因为它是在一个查询中完成的,而不是在递归ORM方法生成的多个查询中完成的


使用
CTE
可以在服务器端实现递归,从而通过单个查询返回所需的结果集。你可以在这里找到很多这样做的例子。