我需要计算分层组织的平均值。
每个学生都可以在不同科目中取得成绩(并非所有学生都有所有科目的成绩),每个学生都有一个家长(这是一个单元)。每个单位都有一个父母,这是另一个单位,依此类推。层次结构树中的分支数量未知(这就是为什么我认为我需要递归方法)。此外,主题的数量是未知的,所以我不能使用任何类似枢轴的技术来理解我。
我的最终目标是使用报表生成器中的Matrix和递归父级功能可视化层次结构,以创建层次结构。
对于持有学生的每个单元,我需要计算每个科目的平均值。对于每个持有单位的单位,我需要计算每个主题的子单位的平均值(意味着平均值)。
我试图采用@JamesZ建议的基于迭代的方法:
insert into temp
select * from UnitsAvg
declare @level int = (select max(level) from hierarchy)
while (@level >= 0)
begin
insert into temp
select h.unitparentid as id, u.subject, avg(AvgGrade) as AvgGrade
from UnitsAvg u
inner join hierarchy h
on u.unitid=h.unitid
where level=@level
group by h.unitparentid, u.subject
@level = @level - 1
end
select * from temp
有些东西在那里有语法,帮助将不胜感激! the fiddle
答案 0 :(得分:1)
这是一个基于迭代的方法来解决这个问题,这可能有帮助,或者其他人可以在没有循环的情况下弄清楚如何进行更新。 CTE的第一部分是弄清楚层次结构中存在哪些主题。它可能不是最佳的,但它是从answer复制到事件问题,因此别名也有点奇怪:)
;with CTE as (
select S.StudentId as UnitID, S.ParentID as UnitParentID,
S.StudentID, Subject, 'S' as Type
from grades S
union all
select U.UnitId, U.UnitParentId,
CTE.StudentId as StudentID, Subject, 'U' as Type
from
Hierarchy U
join CTE
on U.UnitId = CTE.UnitParentId
)
select distinct UnitID, UnitParentId, Subject, -1 as Grade
into #tmp
from CTE
where Type = 'U'
while (1=1) begin
update #tmp
set Grade = (select avg(Grade)
from (
select Grade from grades g
where g.ParentId = #tmp.UnitID and
g.Subject = #tmp.Subject
union all
select Grade from #tmp t
where t.UnitParentID = #tmp.UnitID and
t.Subject = #tmp.Subject
) X
)
where
Grade = -1 and
not exists (
select 1 from #tmp t
where t.UnitParentID = #tmp.UnitID and t.Grade = -1
)
if (@@rowcount = 0) break
end
循环更新值可以更新的单位(=已经计算了它们下面的层次结构)。等级-1用于确定是否已计算该值。如果没有要更新的行,则循环结束。如果单元中有子单元和学生,则两者的成绩均以相同的权重计算。