比方說,我有一個表格,其中包含「user_id,日期和分數」,每個用戶每個月只有一個分數,但並不總是在同一天。如何從oracle sql中獲取下個月的條目?
我想要一個具有「user_id,date,score_delta」的查詢,其中score_delta是分數在「date」和下一個月之間會發生多少變化?難道我將不得不做一些跛像TO_DATE(TO_CHAR(日期,...
比方說,我有一個表格,其中包含「user_id,日期和分數」,每個用戶每個月只有一個分數,但並不總是在同一天。如何從oracle sql中獲取下個月的條目?
我想要一個具有「user_id,date,score_delta」的查詢,其中score_delta是分數在「date」和下一個月之間會發生多少變化?難道我將不得不做一些跛像TO_DATE(TO_CHAR(日期,...
這裏有一種方法(跛行商算出作爲練習留給讀者):
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開始。
我覺得這是一個相當漂亮的 – 2009-10-16 18:37:53
一個警告:如果表中有很多數據,適當的索引可能會變得必要。 – DCookie 2009-10-16 20:09:10
你錯過了一個測試用例 - 如果你放入多個用戶,你會發現你的查詢會交錯用戶的測試結果,因爲唯一的排序是在test_date上。您應該在ORDER BY test_date之前放置一個PARTITION BY user_id。 – 2009-10-17 06:05:52
像這樣的東西應該會返回下個月輸入的user_id,日期和分數。
select user_id, date, score from table where
date between ((select sysdate from dual)
and (select add_months(sysdate, 1) FROM dual));
OP想要一個當前和下個月的分數之間的三角洲... – DCookie 2009-10-16 19:58:00
+1捅了捅我調查分析函數... – DCookie 2009-10-16 22:23:44