2011-10-26 81 views
3

我有一個十進制日期(YYYYMMDD)的字段。我需要找到一年或更少的所有 記錄。由於日期是那麼容易,我 試圖做:如何將十進制日期轉換爲where語句中的日期字段?

WHERE DATE(SUBSTR(CHAR(A.CPADDT),1,4) CONCAT '-' CONCAT 
     SUBSTR(CHAR(A.CPADDT),5,2) CONCAT '-' CONCAT 
     SUBSTR(CHAR(A.CPADDT),7,2)) > CURRENT_DATE - 1 YEAR 

這在SELECT部分的偉大工程。當我把它放在WHERE 部分時,我得到了「涉及字段* N的選擇錯誤」。

任何想法我做錯了什麼?

+1

你可以顯示你正在使用的完整查詢?和工作查詢嗎?另外,你使用的是什麼RDBMS? – Lamak

+0

RDBMS是IBM i(或標籤狀態的IBM中端)。 –

回答

2

Selection error involving field *N.表示您的表格中的日期無效。

檢查工作日誌中的CPD4019。原因將包括錯誤日期的相對記錄編號。

Message . . . . : Select or omit error on field &10 member &1.    
Cause . . . . . : A select or omit error occurred in record &5, record  
    format &7, member number &8 of file &2 in library &3, because of condition 
    &6 of the following conditions:           

您還可以使用喬恩斯基特的解決方案內嵌像這樣

WHERE A.CPADDT > YEAR(CURRENT_DATE - 1 YEAR) * 10000     
+ MONTH(CURRENT_DATE - 1 YEAR) * 100 + DAY(CURRENT_DATE - 1 YEAR) 

,而不必擔心日期轉換錯誤可言,除了其他好處。

+0

這是我開始考慮去的地方,但是我確實發現了我的問題。請參閱下面的答案。 –

4

幸運的是,YYYYMMDD按照自然順序結束。因此,與其解析記錄不同,爲什麼不從一年前「格式化」日期,並對此進行比較?

目前還不清楚你在哪裏調用它,以及你是否可以在那裏提供邏輯,但如果沒有,並且這是在一個存儲過程中,你可以隨時把邏輯放在那裏。基本上你想擁有像(僞代碼):

CUTOFF = CURRENT_DATE - 1 YEAR 
CUTOFF_NUMERIC = CUTOFF.YEAR * 10000 + CUTOFF.MONTH * 100 + CUTOFF.DAY 
SELECT ... FROM A WHERE A.CPADDT > CUTOFF_NUMERIC 

道歉不能夠給你實際代碼 - 我不熟悉SQL方言,而我遠無論如何,從一個SQL專家。希望這足以提供一個建議,讓你儘管。請注意,這也應該有助於提高性能 - 如果您在CPADDT上有索引,那麼此查詢可以輕鬆使用它,而您的原始嘗試可能不會。即使你的沒有有索引,簡單的數字比較可能比所有的格式化和解析都便宜。

+0

如果它們位於ibm-midrange框中,並且它們具有六個字符的字段名稱(以及一個8位數字日期),那麼最可能的結果是他們正在使用DB2來對付'傳統'表。可能從RPG程序運行(儘管可能有更多的現代語言);如果是這樣,有幾個函數可以讓他們採用'日期'類型並將其直接轉換爲數字格式(然後再返回)。哪個(正如你所指出的)當然是索引的最佳選擇。 –

0

這兩個以前的答案都很好。實際上,我是一個糟糕的程序員,並沒有100%確定數據是有效的。有一些「零日期」在哪裏不應該有。我從查詢中刪除了它的工作。

A.CPADDT <> 0 AND DATE(SUBSTR(DIGITS(A.CPADDT),1,4) CONCAT '-' CONCAT 
    SUBSTR(DIGITS(A.CPADDT),5,2) CONCAT '-' CONCAT   
    SUBSTR(DIGITS(A.CPADDT),7,2)) > CURRENT_DATE - 1 YEAR 

在這種特殊情況下,我們只包括自我查找的數據,如果一個人願意看到自己的付款狀態。我可能沒有這樣做,因爲我確信沒有任何用戶輸入的日期驗證(該程序可能是15歲以上)。

+0

你應該看看扭轉這個功能,正如其他人所建議的。這將允許您使用任何現有的標記。以及當其他'0'(或以其他方式無效)日期添加時不會轟炸。而且你應該考慮把這個切換到一個實際的'日期'欄,這將允許你避免大部分的麻煩(並且在一個有類似復古程序的舊店中工作,我知道這可能是非常困難的...... )。 –

+0

我一直在思考如何處理無效日期。 @JamesA的解決方案可能是最好的避免這種情況。特別是因爲這是在沒有真正監控的後臺進程中運行的。 –

+0

無論如何,你是否真的需要插入連字符('-')?你試過簡單的日期(DIGITS(A.CPADDT))> CURRENT_DATE - 1年? –

相關問題