2009-10-16 3 views
1

"user_id, date, score"가있는 테이블을 가지고 있고 모든 사용자가 매월 정확하게 하나의 점수를 지지만 항상 같은 날에있는 것은 아니라고 가정 해 봅시다.oracle sql에서 다음 달에 항목을 얻으려면 어떻게해야합니까?

"user_id, date, score_delta"가있는 쿼리를 원하지만 score_delta는 "date"와 다음 달 사이에 점수가 얼마만큼 변경 될까요? ? 나는 ..., TO_DATE 같은 절름발이 일 (TO_CHAR (날짜를해야 할 것

+0

한 ... – DCookie

답변

1

여기 (파행 지수 계산은 독자에게 운동)로 남아 하나 개의 방법이 있습니까 :

CREATE TABLE scores (user_id VARCHAR2(32), test_date DATE, score NUMBER); 

INSERT INTO scores VALUES('U1',SYSDATE-61, 85); 
INSERT INTO scores VALUES('U1',SYSDATE-31, 89); 
INSERT INTO scores VALUES('U1',SYSDATE, 92); 
INSERT INTO scores VALUES('U2',SYSDATE-61, 65); 
INSERT INTO scores VALUES('U2',SYSDATE-31, 89); 
INSERT INTO scores VALUES('U2',SYSDATE, 84); 

COMMIT; 

SELECT s1.user_id, s1.test_date, s2.score-s1.score delta 
    FROM scores s1 
     JOIN (SELECT user_id, trunc(test_date,'MM') test_date, score FROM scores) s2 
     ON (s1.user_id = s2.user_id AND 
      trunc(add_months(s1.test_date,1),'MM') = s2.test_date); 

USER_ID       TEST_DATE  DELTA 
-------------------------------- --------- ---------- 
U1        9/15/2009   3 
U1        8/16/2009   4 
U2        9/18/2009   -5 
U2        8/19/2009   24 

편집 : 그것은 느린 오후, 그래서 나는 LAG 함수를 사용하여 위를 더욱 현재의 세기 ;-)로 자신을 끌어 (이벤트 10g의이 분석 함수 물건을 조사하기로 결정하고, 재 작성 : 생산

SELECT user_id, test_date, score 
    , LAG(score, 1, NULL) OVER (PARTITION BY user_id ORDER BY test_date DESC) - score delta 
    , LAG(score, 1, NULL) OVER (PARTITION BY user_id ORDER BY test_date DESC) AS next_score 
    FROM scores 
ORDER BY 1, 2 DESC; 

를 :

USER_ID       TEST_DATE  SCORE  DELTA NEXT_SCORE 
-------------------------------- ----------- ---------- ---------- ---------- 
U1        10/19/2009   92    
U1        9/18/2009   89   3   92 
U1        8/19/2009   85   4   89 
U2        10/19/2009   84    
U2        9/18/2009   89   -5   84 
U2        8/19/2009   65   24   89 

보세요, 엄마! 자기 조인은 필요 없습니다! 이제는 매끄러운 ;-) (제쳐두고, 설명 계획은 자체 조인이 효율적이지 않음을 나타냅니다.)

스프링 보드로서 저는이 asktom.com question으로 시작했습니다.

+0

나는 이것이 매우 매끄러운 생각 –

+0

하나 개주의 : 테이블은 많은 양의 데이터가있는 경우, 해당 인덱스가 필요한 될 수 있습니다. – DCookie

+1

테스트 사례가 누락되었습니다. 하나 이상의 사용자를 배치하면 test_date에서만 순서가 지정되므로 쿼리가 다른 사용자의 테스트 결과를 인터리빙합니다. ORDER BY test_date 앞에 PARTITION BY user_id를 두어야합니다. –

0

다음과 같이 입력 한 user_id, 날짜 및 점수를 반환해야합니다. 분석 기능을 조사하기 위해 나를 괴롭히는위한

select user_id, date, score from table where 
date between ((select sysdate from dual) 
and (select add_months(sysdate, 1) FROM dual)); 
+0

OP는 현재와 다음 달 점수 사이의 델타를 원했습니다 ... – DCookie

관련 문제