SQL动态WHERE子句难题:合并含LIKE与NOT LIKE的查询
解决SQL查询合并问题:替代CASE实现动态WHERE子句
嘿,我懂你碰到的这个棘手问题了——用CASE来处理带LIKE/NOT LIKE的分支条件确实容易卡壳,其实换个思路,直接用逻辑运算符组合条件块就能完美搞定!
先拆解下你两个查询的核心逻辑:
- 两个查询都要求
COL1 = 10,这是共同条件,可以先提取出来简化代码 - 剩下的条件是完全互斥的日期分支:
- 当
LOG_DATE >= '2016-07-01'时,需要匹配COL2 LIKE '%DATA-1%' - 当
LOG_DATE < '2016-07-01'时,需要匹配COL2 NOT LIKE '%DATA-2%'
- 当
因为这两个日期范围没有重叠,直接用OR把两组条件括起来,再和共同条件用AND连接就可以了。合并后的查询如下:
SELECT * FROM TABLE_NAME X WHERE X.COL1 = 10 AND ( -- 对应原Query-1的条件 (X.LOG_DATE >= TO_DATE('07/01/2016', 'MM/DD/YYYY') AND X.COL2 LIKE '%DATA-1%') OR -- 对应原Query-2的条件 (X.LOG_DATE < TO_DATE('07/01/2016', 'MM/DD/YYYY') AND X.COL2 NOT LIKE '%DATA-2%') )
为什么这个方案比CASE更合适?
CASE表达式本质是用来返回具体值的(比如根据条件返回不同列值或常量),而咱们这里需要的是逻辑判断的分支,用AND/OR组合条件块是更直接、高效的写法,数据库也能更好地优化执行计划。
如果硬要用CASE实现,写法会非常绕,可读性极差,比如:
SELECT * FROM TABLE_NAME X WHERE X.COL1 = 10 AND CASE WHEN X.LOG_DATE >= TO_DATE('07/01/2016', 'MM/DD/YYYY') THEN CASE WHEN X.COL2 LIKE '%DATA-1%' THEN 1 ELSE 0 END WHEN X.LOG_DATE < TO_DATE('07/01/2016', 'MM/DD/YYYY') THEN CASE WHEN X.COL2 NOT LIKE '%DATA-2%' THEN 1 ELSE 0 END ELSE 0 END = 1
显然完全没必要这么写,所以优先推荐第一种逻辑运算符组合的方案。
内容的提问来源于stack exchange,提问作者Rajesh Kumar
相关产品推荐
相关产品推荐

