如何从oracle sql获取下个月的条目?

时间:2009-10-16 17:38:09

标签: sql oracle plsql

假设我有一个包含“user_id,date,score”的表格,每个用户每月只有一个分数,但并不总是在同一天。

我想要一个包含“user_id,date,score_delta”的查询,其中score_delta是“日期”和下个月之间得分的变化程度?我是否必须做一些蹩脚的事情,比如to_date(to_char(date,...?

2 个答案:

答案 0 :(得分: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

编辑:这是一个缓慢的下午,所以我决定研究10g提供的这些分析功能(进一步拖入本世纪;-),并使用LAG功能重写上述内容:

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开始。

答案 1 :(得分: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));