我有一个十进制日期字段(YYYYMMDD)。我需要找到所有 一年或更短的记录。由于日期很简单,我是 试图做:
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.”
我做错了什么想法?
答案 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
上有索引,那么此查询可以轻松使用它,而您的原始尝试可能无法使用。即使你没有有索引,简单的数字比较也可能比所有格式化和解析都便宜。
答案 1 :(得分: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:
你也可以像这样使用 Jon Skeet的内联解决方案
WHERE A.CPADDT > YEAR(CURRENT_DATE - 1 YEAR) * 10000
+ MONTH(CURRENT_DATE - 1 YEAR) * 100 + DAY(CURRENT_DATE - 1 YEAR)
除了其他好处之外,根本不必担心日期转换错误。
答案 2 :(得分: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年)。