【问题标题】:oracle where clause with case whenoracle where 子句与 case when
【发布时间】:2017-10-24 19:15:44
【问题描述】:

我试图避免使用动态 sql。我需要检查参数中的值,并根据它应用正确的子句。

例如:

select * from table
WHERE 1 =
CASE
    WHEN channel = 1 AND REGEXP_LIKE(LOGIN, '[[:digit:]]') THEN 1--only numbers
    WHEN channel = 2 AND LOGIN LIKE 'MI|%' THEN 1
    WHEN channel = 3 AND LOGIN NOT LIKE 'MI|%' AND NOT REGEXP_LIKE(LOGIN, '^\d+(\.\d+)?$', '') THEN 1 --except what is being filtered on case 1 and 2
    ELSE 0
END    

来自 LOGIN 列的样本数据:

VIC.A67923
2013836
257551
GAB.A53272
MI|1234
MI|5345

单独运行过滤器,它们工作正常,但测试为参数分配正确的值,它返回错误的数据。

例如当传递 1 时,它应该只返回那些有数字的,但它也返回有文本的数据。

【问题讨论】:

  • 显示示例表数据
  • @OldProgrammer 完成。所以对于值 1,它应该只返回第 2 行和第 3 行;对于值 2,仅第 5 行和第 6 行;对于值 3,第 1 行和第 4 行。
  • 您意识到您的所有案例都返回值 1,对吧?这就是为什么您总是会返回所有行。
  • @DStanley 我认为只有正确的子句才会返回 1 以匹配 where 子句中的 1,这是错误的吗?
  • 请不要编辑您的问题来纠正问题。添加显示更正的答案或将正确的查询添加到您的问题。它会使其他正在阅读您的问题并试图确定问题所在的人感到困惑。

标签: sql oracle case


【解决方案1】:

您没有锚定并重复您的数字检查。将其锚定到字符串的开头和结尾。你所有的情况都返回 1,所以它最终什么都不做

SELECT *
  FROM tablea
 WHERE 1 = CASE WHEN channel = 1 AND REGEXP_LIKE (login, '^[[:digit:]]*$')
               THEN 1                                                                                      --only numbers
               WHEN channel = 2 AND login LIKE 'MI|%'
               THEN 1
               WHEN channel = 3 AND login NOT LIKE 'MI|%' AND NOT REGEXP_LIKE (login, '^\d+(\.\d+)?$', '')
               THEN 1                                                     --except what is being filtered on case 1 and 2
               ELSE 1
           END

【讨论】:

  • 如果我改为 1,2,3,4 ... 那么 WHERE 1= 只有在 channel =1 时才有效?
  • 知道了。我的 else 应该是 0。谢谢
【解决方案2】:

改变你的情况

CASE
    WHEN channel = 1 AND REGEXP_LIKE(LOGIN, '[[:digit:]]') 
        THEN 1--only numbers
    WHEN channel = 2 AND LOGIN LIKE 'MI|%' 
        THEN 2
    WHEN channel = 3 AND LOGIN NOT LIKE 'MI|%' AND NOT REGEXP_LIKE(LOGIN, '^\d+(\.\d+)?$', '') 
        THEN 3 --except what is being filtered on case 1 and 2
    ELSE 4
END

或者,如果channel 是一个输入参数:

WHERE channel =
    CASE
        WHEN REGEXP_LIKE(LOGIN, '[[:digit:]]') 
            THEN 1--only numbers
        WHEN LOGIN LIKE 'MI|%' 
            THEN 2
        WHEN LOGIN NOT LIKE 'MI|%' AND NOT REGEXP_LIKE(LOGIN, '^\d+(\.\d+)?$', '') 
            THEN 3 --except what is being filtered on case 1 and 2
        ELSE 4
    END

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-01-21
  • 2019-04-05
  • 1970-01-01
  • 1970-01-01
  • 2016-03-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多