Получить несколько сумм в древовидной структуре
У меня есть древовидная структура в таблице employees (id, name, parentid), и эта таблица может быть вложенной.employees-это отношение один ко многим к другой таблице Sales со столбцами(id, employeeid, quantity). У каждого сотрудника есть количество продаж. Я хочу рассчитать сумму количества для каждого сотрудника вместе с дочерними сотрудниками. Я написал некоторый код, чтобы быть более ясным.
DECLARE @Employees TABLE(ID INT, Name NVARCHAR(100), ParentID INT); DECLARE @Sales TABLE(ID INT, EmployeeID INT, Quantity INT); INSERT INTO @Employees(ID, Name, ParentID)VALUES (1,N'Employee1', NULL), (2,N'Employee2', 1), (3,N'Employee3', 2), (4,N'Employee4', NULL), (5,N'Employee5', 4), (6, N'Employee6', 5) INSERT INTO @Sales(ID, EmployeeID, Quantity)VALUES (1,1,4), (2,1,2), (3,2,3), (4,3,2), (5,3,7), (6,5,8), (7,5,3), (8,6,2)
Я присоединился к этим столам и выглядит это так: Объединенные Таблицы
Что я уже пробовал:
Вот мой запрос
;WITH cte AS ( SELECT e.ID, e.Name, e.ParentID FROM @Employees e WHERE e.ParentID IS NULL UNION ALL SELECT e.ID, e.Name, e.ParentID FROM @Employees e INNER JOIN cte c ON c.ID = e.ParentID ) SELECT c.ID ,c.Name ,c.ParentID ,ISNULL(SUM(s.Quantity), 0) AS ParentSumSales ,ISNULL(LEAD(SUM(s.Quantity)) OVER(ORDER BY c.ID), 0) AS ChildSumSales FROM cte c LEFT JOIN @Sales s ON s.EmployeeID = c.ID GROUP BY c.ID, c.Name, c.ParentID
запрос возвращает этот результат, но он неверен. Возвращаемый результат
Возвращаемый результат должен быть таким:
ID Name ParentSumSales ChildSumSales --- --------- ------------- ------------- 1 Employee1 6 12 2 Employee2 3 9 3 Employee3 9 0 4 Employee4 0 13 5 Employee5 11 2 6 Employee6 2 0
Как я могу написать запрос, чтобы получить эти данные?
RossMW
Возможно, вам придется переосмыслить то, чего вы пытаетесь достичь. В своем запросе вы пытаетесь суммировать значения из рекурсивного цикла, но этот цикл может иметь один или несколько рекурсивных уровней. Я не вижу, как это достигается в операторе select. Чтобы достичь этого чисто в SQL, вам, вероятно, понадобится табличная функция, но она может быть сложной и медленной. Ниже приведен пример рекурсивной функции для получения самого верхнего employeeid данного сотрудника в качестве руководства или отправной точки.
< pre lang= "SQL">
Создайте функцию dbo.FindParent (@ID int)
возвращает значение типа int
АС
НАЧАТЬ
Объявить @parent int
Объявить @tmp int
Объявить @counter int
set @tmp = @ID
set @parent = @ID
SET @counter = 1
В то время как @counter < 10 и @tmp не являются нулевыми
НАЧАТЬ
Выберите @ТМП = атрибутом parentId, @родитель = ID от сотрудника где ID = @ТМП
SET @counter = @counter + 1
конец
возвращение @родитель;
конец
ГО
< / pre>