![](/img/trans.png)
[英]DB2 SQL Statement WHERE clause CASE WHEN in multiple conditions
[英]DB2 SQL: Function works in SELECT statement, but not in WHERE clause
我有一个这样的表:
**dNum | dType | dCode | dChar**
1 | blah | foo | xxxx
1 | blah | foo2 | 10/11/2016
2 | blah | foo | xxxx
2 | blah | foo2 | 10/19/2016
... 等等。
对于每一个独特的dNum我需要找到时DCODE等于“foo2的”,然后当dChar 正是在15天前。 我的问题是获取确切的15天前的日期。 我当前的代码如下:
SELECT dNum
,dChar
FROM thing.table boo
WHERE dCode = 'foo2' AND
DAYS(CURRENT_DATE) - DAYS(DATE(dChar)) = 15
当我尝试运行此查询时,出现以下错误:“日期,时间或时间戳记字符串中的值无效。” 但是,令我更加困惑的是,当我将DAYS(CURRENT_DATE) - DAYS(DATE(dChar))
用作我的SELECT语句中的字段而不是WHERE子句中的字段时,它工作得很好。 以下代码对我有用:
SELECT dNum
,dChar
,DAYS(CURRENT_DATE) - DAYS(DATE(dChar)) AS TEST1
FROM thing.table boo
WHERE dCode = 'foo2'
dChar是CHAR(25)变量,并非所有值都是日期,但是同样,当我的代码不在WHERE子句中时,这似乎没有任何影响。
有人可以帮我弄清楚这里发生了什么吗?
如果将where
代码更改为:
WHERE dCode = 'foo2' AND
(case when dcode = 'foo2'
then DAYS(CURRENT_DATE) - DAYS(DATE(dChar))
end) = 15
我意识到这非常不可思议,但是可以保证仅当dcode = 'foo2'
时才评估该函数。 可能发生的情况是,当此条件为真时,值都正确,但问题出在其他地方。
显然,其中dCode
等于“ foo2”的行中的dChar
值是日期的有效表示形式。 由于选择列表是在应用所有WHERE
谓词之后才处理的,因此这不会引起任何问题。
另一方面,如果将DATE(dChar)
放在WHERE
子句中,则它可能会遇到无法转换为日期的dChar
值。
Gordon Linoff建议的解决方案可能会或可能不会(可能是后者)起作用,这取决于优化器如何决定处理CASE
表达式。
编辑:
您的问题是“怎么回事?”,所以现在您知道了。 如果要更进一步,找到一种可靠的解决方法,一种选择是创建一个用户定义的函数,该函数可以优雅地处理无效日期,并使用它代替DATE()
。 该函数可能看起来像
create function to_date_safe (str varchar(20))
returns date
deterministic
no external action contains sql
begin
declare continue handler for sqlstate '22007' -- on conversion error
return null;
return date(str);
end
您的WHERE
子句如下所示
WHERE dCode = 'foo2' AND
DAYS(CURRENT_DATE) - DAYS(to_date_safe(dChar)) = 15
您可能需要用转换错误时返回的实际SQLSTATE值替换“ 22007”。
如果使用嵌套查询进行两次过滤,则可以避免此问题(尝试在过滤掉非日期字符串之前解析非日期字符串)。
SELECT
*
FROM
(
SELECT
dNum,
dChar
FROM
thing.table boo
WHERE
dCode = 'foo2'
AND dChar <> ''
)
foo2
WHERE
DAYS(CURRENT_DATE) - DAYS(DATE(dChar)) = 15
编辑
或者,甚至更好的是,对查询重新排序。 将您的日期转换为字符串,而不是相反。 然后可以使用索引,并且非日期格式的值不会引起问题。
WHERE
dCode = 'foo2'
AND dChar = CHAR(CURRENT_DATE - 15 DAYS)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.