Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2008 Forums
 Transact-SQL (2008)
 Average Calculation

Author  Topic 

mystifier
Starting Member

12 Posts

Posted - 2012-05-16 : 11:09:45
I need to calculate the average of ten kpi scores that can have values 0,1,2,3 or 4.

The problem is, the data includes values of >4 that need to be ignored.

The below gives me the result I want but it is very inefficient working on thousands of scores.

CONVERT(DECIMAL,
(
(case when kpi1 <5 then kpi1 else 0 end)+
(case when kpi2 <5 then kpi2 else 0 end)+
(case when kpi3 <5 then kpi3 else 0 end)+
(case when kpi4 <5 then kpi4 else 0 end)+
(case when kpi5 <5 then kpi5 else 0 end)+
(case when kpi6 <5 then kpi6 else 0 end)+
(case when kpi7 <5 then kpi7 else 0 end)+
(case when kpi8 <5 then kpi8 else 0 end)+
(case when kpi9 <5 then kpi9 else 0 end)+
(case when kpi10 <5 then kpi10 else 0 end)
))
/
CONVERT(DECIMAL,
NULLIF(
(
(case when kpi1 <5 then 4 else 0 end)+
(case when kpi2 <5 then 4 else 0 end)+
(case when kpi3 <5 then 4 else 0 end)+
(case when kpi4 <5 then 4 else 0 end)+
(case when kpi5 <5 then 4 else 0 end)+
(case when kpi6 <5 then 4 else 0 end)+
(case when kpi7 <5 then 4 else 0 end)+
(case when kpi8 <5 then 4 else 0 end)+
(case when kpi9 <5 then 4 else 0 end)+
(case when kpi10 <5 then 4 else 0 end)
)
,0))


Can anyone offer a more elegant solution?

RL
Starting Member

15 Posts

Posted - 2012-05-16 : 14:04:23
You can use UNPIVOT to create one row per kpi/value pair, then a regular aggregate query to get the average for each row from the source table.

NOTE: I'm assuming that the source data is in a table named KPI, the values are INT, and there's a unique INT rowID for each row.

;WITH CTE
AS
(
SELECT rowID, kpi, value
FROM KPI
UNPIVOT(value FOR kpi IN (kpi1, kpi2, kpi3, kpi4, kpi5, kpi6, kpi7, kpi8, kpi9, kpi10)) u
)
SELECT rowID,
SUM(CAST(value AS DEC)) / (4.0 * COUNT(*)) AS avg_value
FROM CTE
WHERE value < 5
GROUP BY rowID;

Go to Top of Page

mystifier
Starting Member

12 Posts

Posted - 2012-05-16 : 16:43:50
Thanks RL

I really wanted something I could use as a calculated field but your query is a good idea and I may think about using it to create a view.
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2012-05-16 : 19:57:42
quote:
Originally posted by mystifier

Thanks RL

I really wanted something I could use as a calculated field but your query is a good idea and I may think about using it to create a view.



you can use it as a calculated field by making logic as a UDF

------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/

Go to Top of Page

mystifier
Starting Member

12 Posts

Posted - 2012-05-17 : 03:56:46
Thanks Visakh16,

Sorted. I am gradually making the transition from beginner to novice.
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2012-05-19 : 15:08:24
no problem
you're welcome

------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/

Go to Top of Page
   

- Advertisement -