I'm trying to generate a summary from a list of scores in SQL Server 2008.
I have two tables: SQL Fiddle link
The ScorePerson
table contains people's ID and their score from -5 to 15. End users of my SQL/Stored Procedure needs to create a summary like this:
Scoreband| TotalNoOfPeople | AvgScore
--------------------------------
-5 to 0 | 2 | -2
0 to 5 | 3 | 2
5 to 10 | 2 | 8
10 to 15 | 3 | 13.3
The score band i.e. the min and max values should be configurable from the ScoreMinMax
table by the end user.
I have tried to achive this using CASE stement, but it generates the summary as columns. I I would probably need to pivot it or use UNION from multiple select statements. But this approach doesn't seem scalable if there were new rows added to the ScoreMinMax
table.
So far I was able to achieve some results similar to the example above using CROSS JOINT, but it doesn't always produces the correct results.
Is anyone able to point me in the right direction on how to achieve this please?
ScorePerson - contains actual scores
ScoreMinMax - the configuration for min and max score bands
You can use aggregate functions:
select title ScoreBand,
count(*) TotalNoPeople,
avg(p.score) AvgScore
from scoreperson p
inner join scoreminmax m
on p.score between m.minscore and m.maxscore
group by Title
order by cast(left(title, 2) as int)
If you have no person in an existing range, you can us something like this:
select case when title is not null
then title
else 'No Range' end ScoreBand,
count(personid) TotalNoPeople,
avg(p.score) AvgScore
from scoreperson p
left join scoreminmax m
on p.score between m.minscore and m.maxscore
group by id, Title
order by id
edit #2, based on your comments you can use:
select m.title ScoreBand,
count(p.personid) TotalNoPeople,
avg(p.score) AvgScore
from scoreminmax m
left join scoreperson p
on p.score between m.minscore and m.maxscore
group by m.id, m.Title
order by m.id;