views:

180

answers:

4

I have table with 3 columns(smallint) in SQL Server 2005.

Table Ratings
ratin1 smallint,
ratin2 smallint
ratin3 smallint

These columns can have values from 0 to 5

How to select average value of these fields, but only compare fields where value is greater then 0.

So if column values are 1,3,5 - average had to be 3 if values are 0,3,5 - average had to be 4

+5  A: 

This is kind of quick and dirty, but it will work...

SELECT (ratin1 + ratin2 + ratin3) / 
((CASE WHEN ratin1 = 0 THEN 0 ELSE 1 END) + 
(CASE WHEN ratin2 = 0 THEN 0 ELSE 1 END) + 
(CASE WHEN ratin3 = 0 THEN 0 ELSE 1 END) +
(CASE WHEN ratin1 = 0 AND ratin2 = 0 AND ratin3 = 0 THEN 1 ELSE 0 END) AS Average
mwigdahl
when the three are 0 you would get division by zero, isn't it?
Jhonny D. Cano -Leftware-
+ (CASE WHEN ratin 1 = 0 AND ratin2 = 0 AND ratin3 = 0 THEN 1 ELSE 0 END)
Jhonny D. Cano -Leftware-
Thanks, that's right! Modified answer.
mwigdahl
+1  A: 

There should be an aggregate average function for sql server.

http://msdn.microsoft.com/en-us/library/ms177677.aspx

tmeisenh
There is, but the questioner wants to average across columns, not across rows.
mwigdahl
+2  A: 

You can use the AVG() function. This will get the average for a column. So, you could nest a SELECT statement with the AVG() methods and then SELECT these values.

Pseudo:

SELECT col1, col2, col3
  FROM (
    SELECT AVG(col1) AS col1, AVG(col2) AS col2, AVG(col3) AS col3
      FROM table
) as tbl
WHERE col1 IN (0, 3, 5)
etc.
Ardman
I really don't think this is what the questioner wants. As I read it, he wants to average ratin1, ratin2, and ratin3 within the context of a single row.
mwigdahl
If that is the case, then they can just amend the first SELECT statement to say SELECT AVG(col1 + col2 + col3)
Ardman
`AVG(col1 + col2 + col3)` is the sum of col1, col2, and col3 for single rows
Austin Salonen
What about fields with zero value, I wouldn't like to include it in average, see my question.
barbarian
A: 

This is trickier than it looks, but you can do this:

SELECT dbo.MyAvg(ratin1, ratin2, ratin3) from TableRatings

If you create this function first:

CREATE FUNCTION [dbo].[MyAvg]
(
    @a int,
    @b int,
    @c int
)
RETURNS int
AS
BEGIN
    DECLARE @result int
    DECLARE @divisor int
    SELECT @divisor = 3

    IF @a = 0 BEGIN SELECT @divisor = @divisor - 1 END
    IF @b = 0 BEGIN SELECT @divisor = @divisor - 1 END
    IF @c = 0 BEGIN SELECT @divisor = @divisor - 1 END

    IF @divisor = 0     
        SELECT @result = 0
    ELSE
        SELECT @result = (@a + @b + @c) / @divisor

    RETURN @Result

END
egrunin