2013-02-07 134 views
0

我想弄清楚如何比較where子句中日期減法的結果。Oracle - where子句中的日期減法

訂閱服務的客戶,因此鏈接到具有結束日期的訂閱。我想要顯示在接下來的兩週內即將結束的訂閱列表。 我沒有設計數據庫,但注意到End_Date列的類型是一個varchar而不是日期..我無法改變這一點。

我的問題如下: 如果我儘量選擇減法,例如用如下請求的結果:

SELECT(TO_DATE(s.end_date,'YYYY-MM-DD') - TRUNC(SYSDATE)) , s.name 
from SUBSCRIPTION s WHERE s.id_acces = 15 

這將工作給我的天數認購結束之間和當前日期。

但現在,如果我嘗試包括子句中完全相同的請求,其中比較:

SELECT s.name 
from SUBSCRIPTION S 
WHERE (TO_DATE(s.end_date,'YYYY-MM-DD') - TRUNC(SYSDATE)) between 0 and 16 

我會得到一個錯誤:「ORA-01839:日期不適用於指定的月份」。 任何幫助,將不勝感激..

回答

1

" the End_Date column type is a varchar and not a date.. I can't change that."

如果你不能改變日期,你必須長3油層的數據。

select sid, end_date 
from SUBSCRIPTION 
where check_date_format(end_date) != 'VALID'; 

你的選擇是:

  1. 修正數據,這樣所有的日期

    create or replace check_date_format (p_str in varchar2) return varchar2 
    is 
        d date; 
    begin 
        d := to_date(p_str,'YYYY-MM-DD'); 
        return 'VALID'; 
    exception 
        when others then 
        return 'INVALID'; 
    end; 
    

    您可以在查詢中使用此功能:您可以使用此功能找出流氓值格式相同

  2. 修復數據並應用檢查約束以強制執行將來的有效性
  3. 編寫一個定製的MY_TO_DATE()函數,它接受一個字符串並將大量不同的日期格式掩碼應用於其中,以期獲得成功的轉換。
+0

這是我一直在尋找的要求!非常感謝 ! – Marc

3

在表中的某個地方,你有不同的方式從YYYY-MM-DD格式化日期。在你的第一個查詢中,你檢查某一行(或一組行,s.id_acces = 15),這可能是好的,但在第二次你掃描整個表。

嘗試尋找具有類似這些行,

select end_date from subscription 
where not regexp_like(end_date, '[0-9]{4}-[0-9]{2}-[0-9]{2}') 
+0

+1罪的工資是隱含的數據轉換異常。 – APC

+0

該死的感謝了!幸運的是,我在數據庫中只有150行。問題來自於數據中有2013-09-31的日期。由於9月31日不存在,這就是爲什麼我的請求不會通過。 – Marc

2

檢查您的DD值(即:月日)。該值必須介於1和月份中的天數之間。

January - 1 to 31 
February - 1 to 28 (1 to 29, if a leap year) 
March - 1 to 31 
April - 1 to 30 
May - 1 to 31 
June - 1 to 30 
July - 1 to 31 
August - 1 to 31 
September - 1 to 30 
October - 1 to 31 
November - 1 to 30 
December - 1 to 31 
+0

這確實是個問題。非常感謝,你們都如此反應...... – Marc