找到多行字段的平均值

时间:2014-09-09 13:01:10

标签: sql sql-server

我有一张表评分

part     rating     numReviews
----     ------     ----------
A1       100        5
A1       50         2
A2       90         4
A3       100        4

我需要找到每个部分的平均评分。在上面的例子中,A2是90,A3是100,因为它们是单行。容易。

但是,A1部分是多行,所以我需要为每行做评级* numReviews 然后除以总numReviews

这可能吗?这就是我正在尝试的(微软SQL):

select part, 
cast((AVG((rating * numReviews) / SUM(numReviews))) as decimal(5,2)) as rating_average
from tableName group by part order by part

我收到以下错误:

Cannot perform an aggregate function on an expression containing an aggregate or a subquery.

4 个答案:

答案 0 :(得分:2)

如果评级列存储了各个评级的值(意味着您有4个评级值100,A3总计400,您想知道评级的平均值(计算为total per group / (rating value * rating count))和输出应该是:

part AverageRating
---- ---------------------------------------
A1   85.71428571428571428571428571
A2   90.00000000000000000000000000
A3   100.00000000000000000000000000

然后这个查询就会这样做:

select 
    part, 
    sum(rating * numreviews)/sum(cast(numreviews as decimal(5,2))) as AverageRating
from tableName 
group by part

另一方面,如果评级栏存储评级的总和(意味着A3的值100应解释为4 * 25),并且您希望每组的平均评级具有此输出:

part rating_average
---- ---------------------------------------
A1   21.4285714285714285714
A2   22.5000000000000000000
A3   25.0000000000000000000

然后这个:

with ratings as (select 
    part, 
    sum(rating) r, 
    sum(numreviews) as c
from TableName
group by part
)
select part, avg(r/cast(c as decimal)) AS rating_average
from ratings 
group by part

我认为这是你要找的前者,而不是后者。

答案 1 :(得分:1)

Select part, Sum(rating) as ratings,Sum(numReviews) as TotalReviews,
        (Sum(rating) /sum(numReview )) as rating_average
From tableName
Group By part

答案 2 :(得分:1)

您只需使用SUM

即可
SELECT part, 
    CAST(SUM(rating * numReviews) / SUM(numReviews) AS DECIMAL(5, 2)) as rating_average
FROM tableName
GROUP BY part
ORDER BY part

答案 3 :(得分:0)

或者为了清楚起见,你可以一步一步地做到这一点

SELECT Level1.*,(Level1.ratings/Level1.TotalReviews) as rating_average
FROM
  (
     Select part, Sum(rating) as ratings,Sum(numReviews) as TotalReviews
     From tableName
      GroupBy part
   ) as Level1