2015-04-18 4 views
0

Учитывая следующую схему таблицы, меня спросили, как найти всех подчиненных Анни.Recursion vs Common Table Expression - когда использовать 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; 

преимущество заключается в том, что он является потенциально быстрее, так как это делается в одном запросе против нескольких запросов, генерируемых из рекурсивного метода ORM.

T-SQL Fiddle Example

Смежные вопросы