组织表 科目表
组织 组织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 或 存储过程写出对于我来说难度很大,请各位高人,看看。谢谢了。

解决方案 »

  1.   


    -关于递归累计求和  
    -->>TravyLee生成测试数据  
    if OBJECT_ID('test')is not null  
    drop table test  
    go  
    create table test(  
    id int identity(1,1),  
    deptid char(3),  
    empid char(4),  
    salary int  
    )  
    go  
    insert test(deptid,empid,salary)  
    select '101','1001',3500 union all  
    select '101','1002',2200 union all  
    select '102','1003',1900 union all  
    select '102','1004',5600 union all  
    select '102','1005',8000 union all  
    select '101','1006',2400 union all  
    select '101','1007',2300 union all  
    select '103','1008',3200 union all  
    select '103','1009',7800 union all  
    select '104','1010',4500 union all  
    select '101','1011',6500 union all  
    select '104','1012',3500 union all  
    select '104','1013',1900 union all  
    select '103','1014',2700 union all  
    select '102','1015',3100 union all  
    select '104','1016',2600   
    go  
    --problem 1:求出所有员工的工资的累计(从工资的最高到最低累计)  
    ;with t  
    as(  
    select   
    px=ROW_NUMBER()over(order by salary desc),  
    deptid,empid,salary  
    from test  
    ),  
    m as(  
    select px,deptid,empid,salary,salary as total   
    from t where px=1  
    union all  
    select   
    a.px,a.deptid,a.empid,a.salary,b.total+a.salary  
    from t a  
    join m b on a.px=b.px+1   
    )  
    select deptid,empid,salary,total from m  
    go  
    /*  
    deptid empid salary total  
    ------------------------------  
    1   102 1005    8000    8000  
    2   103 1009    7800    15800  
    3   101 1011    6500    22300  
    4   102 1004    5600    27900  
    5   104 1010    4500    32400  
    6   101 1001    3500    35900  
    7   104 1012    3500    39400  
    8   103 1008    3200    42600  
    9   102 1015    3100    45700  
    10  103 1014    2700    48400  
    11  104 1016    2600    51000  
    12  101 1006    2400    53400  
    13  101 1007    2300    55700  
    14  101 1002    2200    57900  
    15  102 1003    1900    59800  
    16  104 1013    1900    61700  
    */  
      
    --problem 2:分部门统计,并求出各部门在总工资中所占的百分比  
      
    ;with t  
    as(  
    select   
    px=ROW_NUMBER()over(partition by deptid order by salary desc),  
    deptid,empid,salary  
    from test  
    ),  
    m as(  
    select px,deptid,empid,salary,salary as total   
    from t where px=1  
    union all  
    select   
    a.px,a.deptid,a.empid,a.salary,b.total+a.salary  
    from t a  
    join m b on a.px=b.px+1 and a.deptid=b.deptid  
    )  
    select   
        deptid,empid,salary,total   
    from   
        m   
    order by   
        deptid,px  
      
    /*  
    deptid empid salary total  
    ------------------------------  
    101 1011    6500    6500  
    101 1001    3500    10000  
    101 1006    2400    12400  
    101 1007    2300    14700  
    101 1002    2200    16900  
    102 1005    8000    8000  
    102 1004    5600    13600  
    102 1015    3100    16700  
    102 1003    1900    18600  
    103 1009    7800    7800  
    103 1008    3200    11000  
    103 1014    2700    13700  
    104 1010    4500    4500  
    104 1012    3500    8000  
    104 1016    2600    10600  
    104 1013    1900    12500  
    */  
    --参考
      

  2.   

      谢谢上面的大哥,可能我的描述不是很清楚,有没有树形结构子节点有值,求各父项的和的这种SQL ,我参考下这个也行,在网上找到一个 都是以建表更新父节点的数的例子,有没有不用建表的方式,直接查询出的SQL。
        id  pid  lev
         a        1
         b   a    2
         b1  a    2
         c1  b    3
         c11 b1   3  数值:   ID,NUM
               C1   5
               C11  10  要得出这种形式
               ID,NUM
               a   15
               b    5
               b1   10
               c1   5
               c11  10
        
      

  3.   


    -- 查询指定部门下面的所有部门, 并汇总各部门的下级部门数
    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
      

  4.   

    谢谢TravyLee ,按照你的提示,我已经做出来了。再次感谢!