2016-09-11 21 views
2

テーブルの従業員(id、name、parentid)にツリー構造があり、このテーブルはネストすることができます.employeesは別のテーブルと1対多の関係です。 、従業員番号、数量)。各従業員には販売数量があります。私は子供の従業員と一緒に各従業員の数量の合計を計算したいと思います。私はより明確になるようにいくつかのコードを書いた。ツリー内の値の合計を計算する(再帰クエリ)

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) 

私はこのテーブルに参加し、好きに見えるこの:
enter image description here

しかし、この:ここ

enter image description here

は、クエリは、この結果を返す

;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 

答えて

1

LEADを使用してみると、以前のレベルを合計していないため、IDは連続している必要があります。

各employeが一度階層レベルごとに含まれるように各従業員のための完全なhierachyは最初の爆発:

;WITH cte 
AS 
(
    SELECT e.ID, e.Name, e.ID as sub_ID 
    FROM @Employees e 
    -- no WHERE-condition to get all employees 
    UNION ALL 
    SELECT 
    c.ID, c.Name -- keep the initial employee 
    ,e.ID as sub_ID 
    FROM @Employees e 
    INNER JOIN cte c ON c.sub_ID = e.ParentID 
) 

SELECT 
    c.ID 
    ,c.Name 
    -- parent level 
    ,sum(case when c.id = s.EmployeeID then s.Quantity else 0 end) AS ParentSumSales 
    -- child level 
    ,sum(case when c.id <> s.EmployeeID then s.Quantity else 0 end) AS ChildSumSales 
FROM cte c 
LEFT JOIN @Sales as s 
ON s.EmployeeID = c.sub_ID 
group by c.Name, c.id 
+0

はい、それは動作します、しかし、左の内側のおかげで何もして、グループを使用する必要があり、合計はありません参加 – www1986

+0

@ www1986:これは元のクエリを修正しようとしていて残っていたもので、それ以降はチェックしなかった:)私はそれに応じて修正する – dnoeth

1

、私はNested set modelを実装することをお勧めいたします。執筆はより複雑になりますが、読書はより簡単で速くなります。

関連する問題