2011-10-26 46 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年? –

相关问题