SQL Server中的AVG和COUNT

时间:2011-12-16 11:06:41

标签: sql sql-server average

我有一个评级系统,任何人都可以评论其他人。每个人可以由一个人不止一次地评判。对于平均值的计算,我想只包括最新的值。

这可以用SQL吗?

  • 人1在1.2.2011评价人2和5< - 因为人的评价较新而被忽略
  • 人1在3.2.2011评价人2与2
  • 人2在1.2.2011评价人1与6< - 忽略
  • 人2在1.3.2011评价人1与3
  • 人3在1.5.2011评价人1与5

结果:

  • 人员2的平均值为2。
  • 人员1的平均值为4。

表格可能如下所示:evaluator, evaluatee, rating, date

亲切的问候

迈克尔

3 个答案:

答案 0 :(得分:5)

这完全有可能。

我们假设您的表结构如下所示:

CREATE TABLE [dbo].[Ratings](
    [Evaluator] varchar(10),
    [Evaluatee] varchar(10),
    [Rating] int,
    [Date] datetime
);

和这样的值:

INSERT INTO Ratings
    SELECT 'Person 1', 'Person 2', 5, '2011-02-01' UNION
    SELECT 'Person 1', 'Person 2', 2, '2011-03-01' UNION
    SELECT 'Person 2', 'Person 1', 6, '2011-02-01' UNION
    SELECT 'Person 2', 'Person 1', 3, '2011-03-01' UNION
    SELECT 'Person 3', 'Person 1', 5, '2011-05-01'

然后人1的平均评分为:

SELECT AVG(Rating) FROM Ratings r1
    WHERE Evaluatee='Person 1' and not exists
    (SELECT 1 FROM Ratings r2
        WHERE r1.Evaluatee = r2.Evaluatee AND
            r1.evaluator=r2.evaluator AND
            r1.date < r2.date)

结果:

4

或者对于所有评估者,按评估者分组:

SELECT Evaluatee, AVG(Rating) FROM Ratings r1
    WHERE not exists
    (SELECT 1 FROM Ratings r2
        WHERE r1.Evaluatee = r2.Evaluatee AND
            r1.evaluator = r2.evaluator AND
            r1.date < r2.date)
    GROUP BY Evaluatee

结果:

Person 1    4
Person 2    2

这可能看起来像隐含的假设,即没有相同日期的条目; 但这实际上不是问题:如果这样的条目可以存在,那么你无法决定以后哪些是后来的;你只能在它们之间随机选择。如此处所示,它们都被包含在内并被平均 - 这可能是你可以获得的最佳解决方案(虽然它略微偏爱那个人,给他两票)。

要完全避免这个问题,您可以简单地将Date作为主键的一部分或唯一索引 - 这里显而易见的主键选择是列(Evaluator,Evaluatee,Date)。

答案 1 :(得分:1)

declare @T table
(
  evaluator int, 
  evaluatee int, 
  rating int,
  ratedate date
)

insert into @T values
(1, 2, 5, '20110102'),
(1, 2, 2, '20110103'),
(2, 1, 6, '20110102'),
(2, 1, 3, '20110103'),
(3, 1, 5, '20110105')

select evaluatee,
       avg(rating) as avgrating 
from (       
      select evaluatee,
             rating,
             row_number() over(partition by evaluatee, evaluator 
                               order  by ratedate desc) as rn
      from @T
     ) as T
where T.rn = 1
group by evaluatee

结果:

evaluatee   avgrating
----------- -----------
1           4
2           2

答案 2 :(得分:0)

这是可能的,但它可能真的很难 - SQL不是为了比较行,而是为了比较列。我强烈建议您保留一个仅包含最新数据的附加表,并将其余表存储在存档表中。

如果必须这样做,那么我需要一个完整的表结构来尝试为此编写查询。特别是我需要知道哪些是独特的索引。