Firebird 2.5 WHERE子句CASE内Boolean表达式报错如何解决
Firebird 2.5日期筛选SQL报错解决方案
报错根因
- Firebird 2.5的
CASE表达式仅支持返回标量值,不支持将布尔判断条件作为返回结果。你将DATUM_NAROCILA BETWEEN ...这类条件语句放在THEN/ELSE分支中,不符合CASE的语法要求,因此解析器遇到BETWEEN关键字时会抛出「Token unknown for BETWEEN」错误。 - 代码中的
'start of previous month'等写法不是Firebird支持的合法日期表达式,需要替换为标准的日期计算语法。
正确实现代码
写法1:直接使用逻辑运算符组合条件
SELECT * FROM FA_DOBAVNICA WHERE 1=1 AND ( -- 当日早于9号取上月数据 (EXTRACT(DAY FROM CURRENT_DATE) < 9 AND DATUM_NAROCILA BETWEEN -- 上月第一天 DATEADD(-1 MONTH TO DATEADD(1 - EXTRACT(DAY FROM CURRENT_DATE) DAY TO CURRENT_DATE)) AND -- 上月最后一天 DATEADD(-1 DAY TO DATEADD(1 - EXTRACT(DAY FROM CURRENT_DATE) DAY TO CURRENT_DATE)) ) OR -- 当日大于等于9号取当月数据 (EXTRACT(DAY FROM CURRENT_DATE) >= 9 AND DATUM_NAROCILA BETWEEN -- 当月第一天 DATEADD(1 - EXTRACT(DAY FROM CURRENT_DATE) DAY TO CURRENT_DATE) AND -- 当月最后一天 DATEADD(-1 DAY TO DATEADD(1 MONTH TO DATEADD(1 - EXTRACT(DAY FROM CURRENT_DATE) DAY TO CURRENT_DATE))) ) )
写法2:使用CTE简化重复日期计算
WITH date_params AS ( SELECT -- 当月第一天 DATEADD(1 - EXTRACT(DAY FROM CURRENT_DATE) DAY TO CURRENT_DATE) AS curr_month_start, -- 当日日期号数 EXTRACT(DAY FROM CURRENT_DATE) AS curr_day FROM RDB$DATABASE ) SELECT f.* FROM FA_DOBAVNICA f, date_params p WHERE 1=1 AND ( (p.curr_day < 9 AND f.DATUM_NAROCILA BETWEEN DATEADD(-1 MONTH TO p.curr_month_start) AND DATEADD(-1 DAY TO p.curr_month_start) ) OR (p.curr_day >=9 AND f.DATUM_NAROCILA BETWEEN p.curr_month_start AND DATEADD(-1 DAY TO DATEADD(1 MONTH TO p.curr_month_start)) ) )
提示:如果
DATUM_NAROCILA是包含时分秒的TIMESTAMP类型,建议将BETWEEN 当月最后一天的写法替换为< 下月第一天,避免因为时间部分不为0导致当月最后一天的数据被遗漏。
内容的提问来源于stack exchange,提问作者Yebach
相关产品推荐
相关产品推荐

