更简单的方法来做多个substr instr OR语句oracle pl sql

时间:2014-12-09 21:05:24

标签: oracle plsql substr

我想检查表列的每2个位置是否存在许多不同的值。 (选择任何符合2位数位置中任何指定值的行) 这是我知道做我需要的唯一方法,但我打赌有一种更清洁,更短的方式:

select *
from table
where 1=1
and (      
Substr(columnA,1,2)  IN ('CE','44','45','87','89','UT','AZ','XX','YY','S1','S2','S3','S4','ES','PM')
                        or Substr(columnA,3,2)  IN ('CE','44','45','87','89','UT','AZ','XX','YY','S1','S2','S3','S4','ES','PM')
                        or Substr(columnA,5,2)  IN ('CE','44','45','87','89','UT','AZ','XX','YY','S1','S2','S3','S4','ES','PM')
                        or Substr(columnA,7,2)  IN ('CE','44','45','87','89','UT','AZ','XX','YY','S1','S2','S3','S4','ES','PM')
                        or Substr(columnA,9,2)  IN ('CE','44','45','87','89','UT','AZ','XX','YY','S1','S2','S3','S4','ES','PM')
                        or Substr(columnA,11,2) IN ('CE','44','45','87','89','UT','AZ','XX','YY','S1','S2','S3','S4','ES','PM')
                        or Substr(columnA,12,2) IN ('CE','44','45','87','89','UT','AZ','XX','YY','S1','S2','S3','S4','ES','PM')
                        or Substr(columnA,14,2) IN ('CE','44','45','87','89','UT','AZ','XX','YY','S1','S2','S3','S4','ES','PM')
                        or Substr(columnA,16,2) IN ('CE','44','45','87','89','UT','AZ','XX','YY','S1','S2','S3','S4','ES','PM') )
;

注意:如果列的值是ABCDEF,并且我们正在检查'BC',则不应找到匹配,只有'AB','CD','EF'应该匹配。

我希望能够列出我要搜索的所有内容。更好的是只列出一次columnA。 我确实找到了一个可能有用的INSTR函数,但我不知道如何在这里应用它。

这有效: Instr(columnA,'XX')IN(1,3,5,7,9,11,14,16)

但对于我正在寻找的每一个价值,有没有比这更好的方法呢? 我可以使用COALESCE吗?

2 个答案:

答案 0 :(得分:3)

使用REGEXP_LIKE匹配regular expression?这样的事情:

'^(..)*((CE)|(44)|(45)|(87)|(89)|(UT)|(AZ)|(XX)|(YY)|(S1)|(S2)|(S3)|(S4)|(ES)|(PM))'
  • ^确保正则表达式锚定到行的开头
  • (..)*吃0到多个字符
  • ((CE)|...)与您的一个有向图匹配。

有关实例,请参阅http://sqlfiddle.com/#!4/d41d8/38453/0

答案 1 :(得分:0)

此答案假设您打算每2个字符进行一次搜索。我假设偶数编号的起始编号不正确:从技术上讲,您在原始问题中搜索重叠的字符串。

由于这是一个常规模式,您可以生成它,这可以帮助您简化查询。

WITH search_pattern AS
        (SELECT     LEVEL * 2 - 1 search_start
         FROM       DUAL
         CONNECT BY LEVEL <= 9)
SELECT DISTINCT t.*
FROM   table1 t CROSS JOIN search_pattern sp
WHERE  SUBSTR (t.columna, search_start, 2) IN 
          ('CE','44','45','87','89','UT','AZ','XX','YY','S1','S2','S3','S4','ES','PM')

在这种情况下,每个位置都有一行,在功能上等同于ordistinct关键字是必要的,以防止多次符合条件的行被多次返回。


虽然这个解决方案很有用,但@ SylvainLeroux使用正则表达式的答案可能会更好。