代码之家  ›  专栏  ›  技术社区  ›  Steven Noble

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

  •  1
  • Steven Noble  · 技术社区  · 15 年前

    假设我有一个表有“用户ID、日期、分数”,每个用户每月只有一个分数,但并不总是在同一天。

    我想要一个有“用户ID,日期,得分三角”的查询,其中得分三角是得分在“日期”和下个月之间会变化多少?我是不是要做一些无聊的事情,比如约会?

    2 回复  |  直到 15 年前
        1
  •  1
  •   DCookie    15 年前

    以下是一种方法(残缺商计算留给读者作为练习):

    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 .

        2
  •  0
  •   David Harris    15 年前

    类似这样的操作应该返回下个月输入的用户ID、日期和分数。

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