Question

Base on the following output

enter image description here

I would like to aggregate amounts at ancestor levels, ie, city/state/country. For example: In the example above we have the country Australia and two states (VIC and NSW). The VIC state has two cities (Melbourne and Bendigo) and NSW has no cities. The result of the query should show exactly the same number of records but aggregate amounts at ancestor levels. Say, Melbourne should show 800, VIC should show 1300, and Australia 2500 as show below:

enter image description here

Would it be possible to do that using a recursive CTE using GetAncestor function of hierarchyid?

CREATE TABLE #Test ( EmployeeNode hierarchyid, EmployeeName varchar(50), Location varchar(50), Amount decimal )

ALTER TABLE #Test ADD [Level] as EmployeeNode.GetLevel()

INSERT INTO #Test (EmployeeNode, Location, EmployeeName, Amount) VALUES (CAST('/0/' AS hierarchyid), 'Australia', NULL, NULL)

INSERT INTO #Test (EmployeeNode, Location, EmployeeName, Amount) VALUES (CAST('/0/1/' AS hierarchyid), 'VIC', NULL, NULL)

INSERT INTO #Test (EmployeeNode, Location, EmployeeName, Amount) VALUES (CAST('/0/1/1/' AS hierarchyid), 'Melbourne', NULL, NULL)

INSERT INTO #Test (EmployeeNode, Location, EmployeeName, Amount) VALUES (CAST('/0/1/1/1/' AS hierarchyid), NULL, 'Mary', 300.00)

INSERT INTO #Test (EmployeeNode, Location, EmployeeName, Amount) VALUES (CAST('/0/1/1/2/' AS hierarchyid), NULL, 'Timothy', 500.00)

INSERT INTO #Test (EmployeeNode, Location, EmployeeName, Amount) VALUES (CAST('/0/1/2/' AS hierarchyid), 'Bendigo', NULL, NULL)

INSERT INTO #Test (EmployeeNode, Location, EmployeeName, Amount) VALUES (CAST('/0/1/2/1/' AS hierarchyid), NULL, 'Paul', 500.00)

INSERT INTO #Test (EmployeeNode, Location, EmployeeName, Amount) VALUES (CAST('/0/2/' AS hierarchyid), 'NSW', NULL, NULL)

INSERT INTO #Test (EmployeeNode, Location, EmployeeName, Amount) VALUES (CAST('/0/2/1/' AS hierarchyid), 'NSW', 'Peter', 1200.00)

SELECT t.EmployeeNode.ToString(), t.* FROM #Test t

Was it helpful?

Solution

declare @Test as Table ( EmployeeNode HierarchyId, EmployeeName VarChar(50), Location VarChar(50), Amount Decimal );

insert into @Test ( EmployeeNode, Location, EmployeeName, Amount ) values
  ( Cast( '/0/' as HierarchyId ), 'Australia', NULL, NULL ),
  ( Cast( '/0/1/' as HierarchyId ), 'VIC', NULL, NULL ),
  ( Cast( '/0/1/1/' as HierarchyId ), 'Melbourne', NULL, NULL ),
  ( Cast( '/0/1/1/1/' as HierarchyId ), NULL, 'Mary', 300.00 ),
  ( Cast( '/0/1/1/2/' as HierarchyId ), NULL, 'Timothy', 500.00 ),
  ( Cast( '/0/1/2/' as HierarchyId ), 'Bendigo', NULL, NULL ),
  ( Cast( '/0/1/2/1/' as HierarchyId ), NULL, 'Paul', 500.00 ),
  ( Cast( '/0/2/' as HierarchyId ), 'NSW', NULL, NULL ),
  ( Cast( '/0/2/1/' as HierarchyId ), 'NSW', 'Peter', 1200.00 );

select EmployeeNode.ToString(), *, EmployeeNode.GetLevel() as [Level],
  ( select Sum( Amount )
      from @Test where EmployeeNode.IsDescendantOf( P.EmployeeNode ) = 1 ) as [Total]
  from @Test as P;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top