如何在 SQL 的 WHERE CLAUSE 中的 CASE 内添加 sql“BETWEEN”条件

Posted

技术标签:

【中文标题】如何在 SQL 的 WHERE CLAUSE 中的 CASE 内添加 sql“BETWEEN”条件【英文标题】:How to add sql "BETWEEN" conditions inside CASE within WHERE CLAUSE in SQL 【发布时间】:2021-02-11 09:31:59 【问题描述】:

我有一个 sql 查询,我需要根据一个条件在 where 子句中添加不同的语句(语句之间)。如果 TX.APPLICATION_ID 是“CONV”,那么我需要在 SYS_CREATION_DATE 添加过滤日期范围,如果 APPLICATION_ID 不是“CONV”,那么我需要在 TRANS_DATE 添加过滤日期范围。这是我正在尝试并收到“缺少关键字”错误的内容。请建议

WHERE TX.TRANS_TYPE IN ('CREDIT', 'CREDITR','CREDITR9', 'DSPJUS')  
  AND 
    CASE
    WHEN TRIM(TX.APPLICATION_ID) = 'CONV' 
    THEN 
      TX.SYS_CREATION_DATE  BETWEEN  TO_DATE('20200831', 'YYYYMMDD')  AND  TO_DATE('20200831', 'YYYYMMDD')
    ELSE 
       TX.TRANS_DATE BETWEEN TO_DATE('20200831', 'YYYYMMDD') AND TO_DATE('20200831', 'YYYYMMDD')
    END

【问题讨论】:

别想CASE。只需尝试使用布尔逻辑 AND、OR、NOT 组合您的条件。您不能使用CASE 突然替换语句的任意部分。 【参考方案1】:

您应该删除CASE 表达式逻辑,它通常不属于WHERE 子句。相反,使用香草AND/OR

WHERE
    TX.TRANS_TYPE IN ('CREDIT', 'CREDITR','CREDITR9', 'DSPJUS') AND (
    (
        TRIM(TX.APPLICATION_ID) = 'CONV' AND
        TX.SYS_CREATION_DATE >= date '20200831' AND
        TX.SYS_CREATION_DATE < date '20200901'
    )
    OR
    (
        TRIM(TX.APPLICATION_ID) <> 'CONV' AND
        TX.TRANS_DATE >= date '20200831' AND
        TX.TRANS_DATE < date '20200901'
    ))

【讨论】:

谢谢蒂姆。这种语法有效:) 但是您能否建议在 where 子句中使用 case 不是一个好习惯? @Venkat Well CASE 表达式用于从给定的输入值生成新值。所以,一般用例是你输入一些列值,然后得到多个可能的值。在WHERE 子句中,主要是检查逻辑条件,而不是生成新值。 @Venkat。 . . case 表达式强制执行评估顺序。这阻碍了优化器,该优化器通常专注于 where 子句中的过滤。

以上是关于如何在 SQL 的 WHERE CLAUSE 中的 CASE 内添加 sql“BETWEEN”条件的主要内容,如果未能解决你的问题,请参考以下文章

SQL 查询在 WHERE CLAUSE 中执行更多记录

MySQLjava.sql.SQLException:Unknown column ‘****‘ in ‘where clause‘错误问题原因以及如何解决?

MySQLjava.sql.SQLException:Unknown column ‘****‘ in ‘where clause‘错误问题原因以及如何解决?

Oracle PL/SQL - 根据条件对不同列进行选择、分组、排序、where-clause 的最佳方法?

SQL where clause with composite values

PostgreSQL 中的 SQL JOIN - WHERE 子句中的执行计划与 ON 子句中的不同