日期:2014-05-18  浏览次数:20513 次

迭代求和问题,给多个树结构子节点的数据组合父项求和。(盼高人进!)

组织表 科目表
组织 组织PID lev 科目 科目PID lev
A 1 K 1
B1 A 2 K1 K 2
B2 A 2 K2 K 2
C11 B1 3 K11 K1 3
C12 B1 3 K12 K1 3
C13 B1 3 K13 K1 3
C21 B2 3 K21 K2 3
C22 B2 3 K22 K2 3
C23 B2 3 K23 K2 3

项目表 其他项表
项目 项目PID lev 其他项 其他项PID lev
X 1 Q 1
X1 X 2 Q1 Q 2
X2 X 2 Q2 Q 2
X11 X1 3 Q11 Q1 3
X12 X1 3 Q12 Q1 3
X13 X1 3 Q13 Q1 3
X21 X2 3 Q21 Q2 3
X22 X2 3 Q22 Q2 3
X23 X2 3 Q23 Q2 3

数据表(由上面各基础表的末级节点组合而成,没有父项数据)
组织 科目 项目 其他项 预算数据 实际数据 年 月份
C11 K11 Q11 4599 4790 2012 5
C11 K12 Q22 4466 4659 2012 6
C11 K13 Q13 4623 2373 2012 5
C11 K21 2747 2331 2012 6
C11 K22 X12 4993 3080 2012 6
C11 K23 X13 2327 2141 2012 5
C12 K12 4161 2592 2012 5
C13 K13 X13 2101 2646 2012 5
C21 K13 X13 2910 3685 2012 5
C22 K21 X11 3674 4608 2012 6
C23 K12 Q12 4404 3582 2012 5
C13 K13 Q13 3867 4013 2012 5
C21 K13 Q21 4927 2396 2012 5
C22 K21 Q22 2764 3965 2012 6
C23 K12 X12 3129 4648 2012 5
C13 K13 X13 3660 2956 2012 6

  需求:根据数据表中各子节点的值表,根据递归原则,用Sql查询出各父项的和值,父项等于其子节点之和。由于涉及4个字段都为树结构,需考虑任意组合的父项数据计算。

查询字段:科目,预算数据,实际数据,可用额度,预算执行率,其中“可用额度”=预算数据-实际数据;“预算执行率”=实际数据/预算数据
查询条件:科目、组织、项目、其他项、年份、月份

有数据的查询条件组合:
1、科目、组织不为空,项目和其他项为空
2、科目、组织、项目不为空,其他项为空
3、科目、组织、其他项不为空,项目为空


要求:1、当查询条件科目选择后,需要查询出该科目的本身和所有后代对应的预算数据、实际数据等等,并以科目分组,查询各科目的和值等等
  2、各字节点值表随业务实时变化,要求根据查询条件实时查询出查询字段的最新值,用一条SQL 或 存储过程写出

对于我来说难度很大,请各位高人,看看。谢谢了。

------解决方案--------------------
SQL code

-- 查询指定部门下面的所有部门, 并汇总各部门的下级部门数
DECLARE @Dept_name nvarchar(20)
SET @Dept_name = N'MIS'
;WITH
DEPTS AS(   -- 查询指定部门及其下的所有子部门
 -- 定位点成员
 SELECT * FROM Dept
 WHERE name = @Dept_name
 UNION ALL
 -- 递归成员, 通过引用CTE自身与Dept基表JOIN实现递归
 SELECT A.*
 FROM Dept A, DEPTS B
 WHERE A.parent_id = B.id
),
DEPTCHILD AS(  -- 引用第1个CTE,查询其每条记录对应的部门下的所有子部门
 SELECT 
  Dept_id = P.id, C.id, C.parent_id
 FROM DEPTS P, Dept C
 WHERE P.id = C.parent_id
 UNION ALL
 SELECT 
  P.Dept_id, C.id, C.parent_id
 FROM DEPTCHILD P, Dept C
 WHERE P.id = C.parent_id
),
DEPTCHILDCNT AS( -- 引用第2个CTE, 汇总得到各部门下的子部门数
 SELECT 
  Dept_id, Cnt = COUNT(*)
 FROM DEPTCHILD
 GROUP BY Dept_id
)
SELECT    -- JOIN第1,3个CTE,得到最终的查询结果
 D.*,
 ChildDeptCount = ISNULL(DS.Cnt, 0)
FROM DEPTS D
 LEFT JOIN DEPTCHILDCNT DS
  ON D.id = DS.Dept_id
GO

-- 删除演示环境
DROP TABLE Dept



本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/fredrickhu/archive/2009/09/19/4569529.aspx