2009-12-31 77 views
4

本質上,我有一個查詢負責在上個月內獲取所有記錄(使用特定的過濾器)。我正在使用Oracle的interval關鍵字,並且所有工作都很好,直到今天(2009年12月31日)。我正在使用的代碼是一個月的時間間隔不能在31日工作?

select (sysdate - interval '1' month) from dual 

和錯誤,我得到它

ORA-01839: date not valid for month specified 

我如何使用間隔關鍵字可與任何兼容的日期?或者如果任何人有更好的方法來解決這個問題,我全都耳熟能詳。

謝謝。

回答

9

嘗試

select add_months(sysdate,-1) from dual 
+0

謝謝。 :) 任何想法,爲什麼add_months()的作品,但不是間隔?是因爲12月份有31天,11月只有30天? – Mike 2009-12-31 13:31:01

+0

不完全確定,但INTERVAL是另一種數據類型(類似於DATE和TIMESTAMP),Steve Feuerstein的PL/SQL書中有關它的所有內容看起來相當複雜。我通常會去做最簡單的事情!自Oracle 7開始,ADD_MONTHS一直在使用DATE類型(即SYSDATE)。 如果要在午夜邊界開始,可能需要使用ADD_MONTHS(trunc(sysdate), - 1)。 – CMG 2009-12-31 13:36:54

+0

完美!感謝您的澄清和代碼修改。 :) – Mike 2009-12-31 13:38:48

2

不是學究氣十足......

的要求是不是很完美規定明確。 「上個月內」的業務意味着什麼?大多數人會認爲這意味着在這種情況下我會使用「當前日曆月內」:

TRUNC(SYSDATE,'MM') 

否則,也許他們希望1個月的當前日期之前的任意時間段 - 但後來怎麼辦你定義了那個?正如您發現的,INTERVAL '1' MONTH只是從日期的月份部分中減去一個 - 例如15-JAN-2009 - INTERVAL '1' MONTH返回15-DEC-1999。對於某些日期,這會導致日期無效,因爲不是所有的月份都有相同的天數。

ADD_MONTHS通過返回本月的最後一天來解決此問題,例如, ADD_MONTHS(31-DEC-2009,-1)返回2009年11月30日。

另一種可能性是企業實際上想要使用平均月份 - 例如, 365/12約爲30.4。他們可能希望你使用​​,儘管當然這樣的12次迭代只能涵蓋一年中的360天。