【问题标题】:Using SQL server hierarchyid how to aggregate leaf node values at ancestor level使用 SQL server hierarchyid 如何在祖先级别聚合叶节点值
【发布时间】:2013-05-19 10:40:00
【问题描述】:

基于以下输出

我想在祖先级别(即城市/州/国家/地区)汇总金额。例如: 在上面的示例中,我们有国家 Australia 和两个州(VIC 和 NSW)。维多利亚州有两个城市(墨尔本和本迪戈),新南威尔士州没有城市。查询的结果应该显示完全相同数量的记录,但在祖先级别汇总数量。比如说,墨尔本应该显示 800,VIC 应该显示 1300,澳大利亚应该显示 2500,如下所示:

是否有可能使用hierarchyid的GetAncestor函数使用递归CTE来做到这一点?

创建表#Test ( EmployeeNode hierarchyid, 员工姓名 varchar(50), 位置 varchar(50), 金额小数 )

改变表#测试 将 [Level] 添加为 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), '墨尔本', 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

【问题讨论】:

    标签: sql-server-2008 tsql common-table-expression hierarchyid


    【解决方案1】:
    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;
    

    【讨论】:

    • 这是很棒的HABO。你当然让它看起来很简单。谢谢。
    • @user1309226 - FWIW,我一直在摆弄使用 CTE。那里似乎没有更好的解决方案。
    • 归根结底,我们感兴趣的是完成工作的最有效方法。你的答案非常适合我。
    猜你喜欢
    • 2011-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多