sql - Aggregative sum of objects belonging to objects residing inside hierarchy structure -
my problem similar in way this one, yet different enough in understanding.
i have 3 tables:
units ([unitid] int, [unitparentid] int)
students ([studentid] int, [unitid] int)
events ([eventid] int, [eventtypeid] int, [studentid] int)
students
belong units, units stacked in hierarchy (tree form - 1 parent per child), , each student can have events of different types.
i need sum number of events of each type per user, aggregate users in unit, aggregate through hierarchy until reach mother of units.
the result should this:
my tools sql server 2008 , report builder 3. put sql fiddle sample data fun.
use query:
;with cte(id, parentid, clevel, title, ord) ( select u.unitid, u.unitparentid, 1, cast('unit ' + cast(row_number() on (order u.unitid) varchar(3)) varchar(max)), cast(right('000' + cast(row_number() on (order u.unitid) varchar(3)), 3) varchar(max)) dbo.units u u.unitparentid null union select u.unitid, u.unitparentid, c.clevel + 1, c.title + '.' + cast(row_number() on (partition c.clevel order c.id) varchar(3)), c.ord + right('000' + cast(row_number() on (order u.unitid) varchar(3)), 3) dbo.units u join cte c on c.id = u.unitparentid u.unitparentid not null ), units ( select u.id, u.parentid, u.clevel, u.title, u.ord, sum(case when e.eventtypeid = 1 1 else 0 end) eventa, sum(case when e.eventtypeid = 2 1 else 0 end) eventb, sum(case when e.eventtypeid = 3 1 else 0 end) eventc, sum(case when e.eventtypeid = 4 1 else 0 end) eventd cte u left join dbo.students s on u.id = s.unitid left join dbo.[events] e on s.studentid = e.studentid group u.id, u.parentid, u.clevel, u.title, u.ord ), addstudents ( select * units union select s.studentid, u.id, u.clevel + 1, 'student ' + cast(s.studentid varchar(3)), u.ord + right('000' + cast(s.studentid varchar(3)), 0), sum(case when e.eventtypeid = 1 1 else 0 end), sum(case when e.eventtypeid = 2 1 else 0 end), sum(case when e.eventtypeid = 3 1 else 0 end), sum(case when e.eventtypeid = 4 1 else 0 end) units u join dbo.students s on u.id = s.unitid left join dbo.[events] e on s.studentid = e.studentid group s.studentid, u.id, u.clevel, u.ord ) select --top(10) replicate(' ', clevel) + title title, eventa, eventb, eventc, eventd addstudents order ord
for this:
title | eventa | eventb | eventc | eventd -----------------+--------+---------+--------+-------- unit 1 | 0 | 1 | 0 | 0 student 6 | 0 | 1 | 0 | 0 unit 1.1 | 0 | 0 | 0 | 1 student 21 | 0 | 0 | 0 | 1 student 33 | 0 | 0 | 0 | 0 unit 1.1.1 | 0 | 0 | 0 | 0 student 23 | 0 | 0 | 0 | 0 unit 1.1.1.1 | 3 | 2 | 3 | 0 student 10 | 0 | 0 | 0 | 0 student 17 | 1 | 0 | 0 | 0 ...
Comments
Post a Comment