2011-12-16 16 views
4

私は他の人が誰かを見直すことができる格付けシステムを持っています。それぞれの人は、一人の人によって複数回審査されます。平均の計算には、最新の値のみを含めることにします。SQL ServerのAVGとCOUNT

これはSQLで可能ですか? 2011年2月1日<の5と

  • 人1つの料金2 - 人の新しい評価は、2011年3月1日
  • 人2つの速度の人の2と1人の
  • 人1人の率2があるので無視2011年2月1日< 6と1に -
  • 者2つのレート3 2011年3月1日に
  • 人3率を持つ人1~5を有する者1
年5月1日にも無視します

結果:evaluator, evaluatee, rating, date

  • 者2の平均は人1 2.
  • 平均は4

ですテーブルは次のようになります。

種類よろしく

マイケル

+0

があなたのテーブルにも代理合成プライマリキーを持っていますか?オートインクリメントID整数、おそらく?クエリがより簡単になり、パフォーマンスが向上する場合は、パフォーマンスが向上します。 –

+0

どのバージョンのSQL Serverですか? – AakashM

答えて

0

これが行うことが可能であるが、それは本当にハリーすることができます - SQLは、行、列のみを比較するように設計されていません。私は強く、最新のデータだけを含む追加のテーブルを保持し、残りをアーカイブテーブルに格納することを強くお勧めします。

もしあなたがにしなければならない場合は、このためのクエリを書くために完全なテーブル構造が必要になります。特に私はどのインデックスがユニークであるかを知る必要があります。

5

これは完全に可能です。

のは、あなたのテーブルの構造は次のようになりますと仮定しましょう:次に者1の平均評価はあり

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' 

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) 

結果

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

と、このような値:

4 

またはすべて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 

結果:

Person 1 4 
Person 2 2 

それはエントリが同じ日付に存在しないことを暗黙の前提を持っているようにこれが見えるかもしれません。 しかし、それは実際問題ではありません。そのようなエントリが存在する可能性がある場合は、後で作成されたエントリを後で決定することはできません。あなたはそれらの間でランダムにしか選択できませんでした。ここに示されているように、それらは両方とも含まれ、平均化されています - あなたがその国境の場合に得られる最良の解決策かもしれません。

この問題を回避するには、主キーまたは一意のインデックスの日付部分を作成するだけで済みます。ここでの主キーの選択は、列(Evaluator、Evaluatee、Date)です。

+0

+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