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