SQL Server中的AVG和COUNT

use*_*780 4 sql sql-server average

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

这可能与SQL有关吗?

  • 人1在2011年1月1日对人2和5进行评分< - 被忽略,因为对人1的评价较新
  • 人1在2011年3月1日评价人2和2
  • 人2对1.2和2011年1月6日的人1进行评分< - 也被忽略
  • 人2在1.3.2011评价人1和3
  • 人3在1.5.2011评价人1与5

结果:

  • 人2的平均值是2.
  • 人1的平均值是4.

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

亲切的问候

迈克尔

cod*_*ing 5

这完全有可能.

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

CREATE TABLE [dbo].[Ratings](
    [Evaluator] varchar(10),
    [Evaluatee] varchar(10),
    [Rating] int,
    [Date] datetime
);
Run Code Online (Sandbox Code Playgroud)

和这样的值:

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'
Run Code Online (Sandbox Code Playgroud)

那么Person 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)
Run Code Online (Sandbox Code Playgroud)

结果:

4
Run Code Online (Sandbox Code Playgroud)

或者由Evaluatee分组的所有Evaluatee:

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
Run Code Online (Sandbox Code Playgroud)

结果:

Person 1    4
Person 2    2
Run Code Online (Sandbox Code Playgroud)

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

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