1

我對與遞歸查詢有關的一些問題感到困惑。
我正在使用SQL SERVER 2012
我的scnerio, 位置被定義爲分層, 每個位置都有自己的資產。
My Locations table like;(CTE)遞歸SQL查詢

Id | Name | ParentLocationId 
----+------+----------------- 
1 | L1 | NULL 
2 | L2 | 1 
3 | L3 | 1 
4 | L4 | 1 
5 | L5 | 1 
6 | L6 | 4 
7 | L7 | 4 
8 | L8 | 4 
9 | L9 | 2 
10 | L10 | 2 
11 | L11 | 6 
12 | L12 | 6 
13 | L13 | 6 

My Asset table like;

Id | AssetNo | Description | CurrentLocationId 
-------+---------+-------------+------------------ 
    1 | AN001 | ADesc  | 1 
    2 | AN002 | BDesc  | 1 

L1具有1,L 2具有如圖2所示,L3具有0,L4具有3,L5具有5,L6具有5,L7具有1, L8具有0,1 L9有3個,L10具有2,L11具有5,L12有3,L13有6個資產

我的問題是,我怎樣才能把所選地點的 1級降資產計數的總數?

例如; SelectedId = 1(L1) Sample Output is;

Id | Name | Qty 
-------+------+----- 
    2 | L2 | 7 
    3 | L3 | 0 
    4 | L4 | 23 
    5 | L5 | 5 

另一個例子;選擇LocationId = 4(L4)

Id | Name | Qty 
---+------+----- 
6 | L6 | 19 
7 | L7 | 1 
8 | L8 | 0 

我嘗試寫一個查詢,

WITH recursiveTable 
    AS (SELECT * 
     FROM location l 
     WHERE ParentLocationId = 1 
     UNION ALL 
     SELECT l.* 
     FROM location l 
       INNER JOIN recursiveTable r 
         ON r.Id = l.ParentLocationId), 
    allLocations 
    AS (SELECT * 
     FROM recursiveTable 
     UNION 
     SELECT * 
     FROM Location 
     WHERE Id = 0), 
    resultset 
    AS (SELECT r.NAME AS LocationName, 
       a.* 
     FROM allLocations r 
     INNER JOIN Asset a ON a.CurrentLocationId = r.Id 
     WHERE r.DataStatus = 1) 

select CurrentLocationId 
     ,min(LocationName) as LocationName 
     ,count(Id) as NumberOfAsset 
from resultset 
group by CurrentLocationId 

附加;

Create Table Location 
    (
     Id int, 
     Name nvarchar(100), 
     Description nvarchar(250), 
     ParentLocationId int, 
     DataStatus int 
    ) 

    Create Table Asset 
    (
     Id int, 
     AssetNo nvarchar(50), 
     Description nvarchar(250), 
     CurrentLocationId int, 
     DataStatus int 
    ) 

    Insert Into Location Values(1,'L1','LDesc1',NULL,1) 
    Insert Into Location Values(2,'L2','LDesc2',1,1) 
    Insert Into Location Values(3,'L3','LDesc3',1,1) 
    Insert Into Location Values(4,'L4','LDesc4',1,1) 
    Insert Into Location Values(5,'L5','LDesc5',1,1) 
    Insert Into Location Values(6,'L6','LDesc6',4,1) 
    Insert Into Location Values(7,'L7','LDesc7',4,1) 
    Insert Into Location Values(8,'L8','LDesc8',4,1) 
    Insert Into Location Values(9,'L9','LDesc9',2,1) 
    Insert Into Location Values(10,'L10','LDesc10',2,1) 
    Insert Into Location Values(11,'L11','LDesc11',6,1) 
    Insert Into Location Values(12,'L12','LDesc12',6,1) 
    Insert Into Location Values(13,'L13','LDesc13',6,1) 

    Insert Into Asset Values (1,'FDB-001','Desc1',1,1) 
    Insert Into Asset Values (2,'FDB-002','Desc2',2,1) 
    Insert Into Asset Values (3,'FDB-003','Desc3',2,1) 
    Insert Into Asset Values (4,'FDB-004','Desc4',4,1) 
    Insert Into Asset Values (5,'FDB-005','Desc5',4,1) 
    Insert Into Asset Values (6,'FDB-006','Desc6',4,1) 
    Insert Into Asset Values (7,'FDB-007','Desc7',5,1) 
    Insert Into Asset Values (8,'FDB-008','Desc8',5,1) 
    Insert Into Asset Values (9,'FDB-009','Desc9',5,1) 
    Insert Into Asset Values (10,'FDB-010','Desc10',5,1) 
    Insert Into Asset Values (11,'FDB-011','Desc11',5,1) 
    Insert Into Asset Values (12,'FDB-012','Desc12',6,1) 
    Insert Into Asset Values (13,'FDB-013','Desc13',6,1) 
    Insert Into Asset Values (14,'FDB-014','Desc14',6,1) 
    Insert Into Asset Values (15,'FDB-015','Desc15',6,1) 
    Insert Into Asset Values (16,'FDB-016','Desc16',6,1) 
    Insert Into Asset Values (17,'FDB-017','Desc17',7,1) 
    Insert Into Asset Values (18,'FDB-018','Desc18',9,1) 
    Insert Into Asset Values (19,'FDB-019','Desc19',9,1) 
    Insert Into Asset Values (20,'FDB-020','Desc20',9,1) 
    Insert Into Asset Values (21,'FDB-021','Desc21',10,1) 
    Insert Into Asset Values (22,'FDB-022','Desc22',10,1) 
    Insert Into Asset Values (23,'FDB-023','Desc23',11,1) 
    Insert Into Asset Values (24,'FDB-024','Desc24',11,1) 
    Insert Into Asset Values (25,'FDB-025','Desc25',11,1) 
    Insert Into Asset Values (26,'FDB-026','Desc26',11,1) 
    Insert Into Asset Values (27,'FDB-027','Desc27',11,1) 
    Insert Into Asset Values (28,'FDB-028','Desc28',12,1) 
    Insert Into Asset Values (29,'FDB-029','Desc29',12,1) 
    Insert Into Asset Values (30,'FDB-030','Desc30',12,1) 
    Insert Into Asset Values (31,'FDB-031','Desc31',13,1) 
    Insert Into Asset Values (32,'FDB-032','Desc32',13,1) 
    Insert Into Asset Values (33,'FDB-033','Desc33',13,1) 
    Insert Into Asset Values (34,'FDB-034','Desc34',13,1) 
    Insert Into Asset Values (35,'FDB-035','Desc35',13,1) 
    Insert Into Asset Values (36,'FDB-036','Desc36',13,1) 

最好的問候,

+0

請閱讀只選擇第一級[**如何問**](http://stackoverflow.com/help/how-to-ask) 和[**如何創建一個最小化,完整和可驗證的示例。**](http://stackoverflow.com/help/mcve) 我們需要樣本數據和期望輸出來更快地找到答案,否則我們會浪費時間猜測您需要什麼。你也可以使用** http://www.sqlfiddle.com** –

+0

創建你的模式。感謝Juan的建議,我會嘗試用數據創建我的模式。 – GKHN

+0

你寫的查詢結果有什麼問題? –

回答

2

我們可以應用LevelPath,試圖讓您的孩子數,但只顯示孩子的第一級。我們最終將路徑中的資產數量分組,這是第一級兒童的ID。那麼,在年底

DECLARE @LocationID INT = 1; 

WITH recursiveCTE AS 
(
    SELECT 
     *, 
     1 AS [Level], 
     Id [Path] 
    FROM 
     location l 
    WHERE 
     l.ParentLocationId = @LocationID 
    UNION ALL 
    SELECT 
     l.*, 
     [Level] + 1, 
     [Path] 
    FROM 
     location l 
     JOIN recursiveCTE r ON l.ParentLocationId = r.Id 
), 
countCte AS (
    SELECT 
     [Path] Id, 
     COUNT(a.AssetNo) Qty 
    FROM recursiveCTE c 
    JOIN Asset a ON c.Id = a.CurrentLocationId 
    GROUP BY [Path] 
) 

SELECT r.Id, 
     r.[Name], 
     COALESCE(c.Qty,0) Qty 
FROM recursiveCTE r 
     LEFT JOIN countCte c ON r.Id = c.Id 
WHERE r.[Level] = 1; 
+0

感謝您的幫助@ JamieD77,也感謝您的解決方案。正是我想要的。 – GKHN

+0

我過去一直認爲這不..真的需要得到複雜的路徑在第一cte ..只是得到ID .. :) – JamieD77