2011-12-16 1 views
4

누구든지 다른 사람을 볼 수있는 등급 시스템이 있습니다. 각 사람은 한 사람이 한 번 이상 판단 할 수 있습니다. 평균 계산을 위해 가장 최근의 값만 포함하고 싶습니다.SQL 서버에서 AVG 및 COUNT

는 SQL과이 가능합니까?

  • 사람 5 1 비율 인 2 1.2.2011 < - 2011년 3월 1일
  • 사람이 요금 사람에 2 사람의 새로운 평가 1
  • 사람 한 요금 사람이 있기 때문에 무시 1.2.2011 <은 6 일에 -
  • 사람이 명 요금 3 2011년 1월 3일에
  • 사람 3 비율을 가진 사람 (1) 5 인 1
년 5월 1일에뿐만 아니라 무시

결과 : 사람 2

  • 평균 인 1 2.
  • 평균 인의 표는 다음과 같이 보일 수 있습니다 4.

입니다 : evaluator, evaluatee, rating, date.

친절 감사

마이클

+0

은 또한 당신의 테이블이 대리 합성 기본 키를 가지고 있습니까? 아마도 자동 증가하는 ID 정수일까요? 그렇다면 쿼리가 더 쉽고 성능이 향상 될 것입니다. –

+0

어떤 버전의 SQL Server입니까? – AakashM

답변

0

이는 할 수 있지만, 그것은 정말 해리 될 수 있습니다 - SQL은 행에만 열을 비교하기 위해 설계되지 않았습니다. 가장 최근의 데이터 만 포함하는 추가 테이블을 보관하고 아카이브 테이블에 나머지를 저장하는 것이 좋습니다.

이 경우에는해야합니다. 그런 다음이 방법으로 쿼리를 작성하려고하면 전체 테이블 구조가 필요합니다. 특히 고유 인덱스가 무엇인지 알아야합니다.

5

완벽하게 가능합니다.

의 당신의 테이블 구조는 다음과 같습니다 가정 해 봅시다 :

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 
); 

와 같은 값 :

Evaluatee별로 그룹화

또는 모든 Evaluatee의에 대한 7,573,213,210 :

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