仅使用WHERE子句组合LIKE和IN

时间:2016-02-10 20:22:44

标签: sql oracle where-in

我知道这个问题已被提出,但我对它的描述略有不同。我有一个用例,我唯一能控制的是查询的WHERE子句,我有2个表。

使用简单的例子:

Table1包含1列名为“FULLNAME”的列,其中包含数百个值 表2包含1个名为“PATTERN”的列,其中包含一些匹配的文本

所以,我需要做的是从表1中选择与表2中的值匹配的所有值。

这是一个简单的例子:

表1(全名)
南极洲 安哥拉
澳大利亚
非洲
印度
印度尼西亚

表2(PATTERN)
AN
IN

有效地我需要的是Table1中包含Table2值的结果(结果将是ANTARCTICA,ANGOLA,INDIA,INDONESIA)

换句话说,我需要的是:

  

从Table1中选择*其中FULLNAME IN LIKE(从'选择'%'|| Pattern ||'%'   表2)

这里棘手的是我只能控制where子句,我根本无法控制Select子句或添加连接,因为我使用的产品只允许控制where子句。我也不能使用存储过程。

这可能吗?

我使用Oracle作为后端数据库

由于

4 个答案:

答案 0 :(得分:3)

一种可能的方法是在子查询中使用EXISTSLIKE结合使用:

select * from table1 t1 
where exists (select null 
              from table2 t2 
              where t1.fullname like '%' || t2.pattern || '%');

答案 1 :(得分:2)

我相信您可以使用简单的JOIN

来完成此操作
SELECT DISTINCT
    fullname
FROM
    Table1 T1
INNER JOIN Table2 T2 ON T1.fullname LIKE '%' || T2.pattern || '%'

DISTINCT用于那些可能与Table2中的多行匹配的情况。

答案 2 :(得分:2)

如果模式总是两个字符,只需要匹配全名的开头,就像你展示的例子一样,你可以这样做:

Select * from Table1 where substr(FULLNAME, 1, 2) IN (Select Pattern from Table2)

这可以防止使用Table1上的任何索引,并且您的实际案例可能需要更灵活......

或者甚至可能效率更低,类似于TomH的方法,但是使用 in 中的子查询:

Select * from Table1 where FULLNAME IN (
  Select t1.FULLNAME from Table1 t1
  Join Table2 t2 on t1.FULLNAME like '%'||t2.Pattern||'%')

答案 3 :(得分:0)

是的,这涉及一些诡计。从概念上讲,我所做的是将列从PATTERN转换为单个单元格,并将其与REGEX_LIKE一起使用

因此值“AN和IN”变为单个值'(AN | IN)' - 我只是将它提供给regexp_like

SELECT FULLNAME from table1  where  
regexp_like(FULLNAME,(SELECT '(' || SUBSTR (SYS_CONNECT_BY_PATH (FULLNAME  , '|'), 2) || ')' Table2
          FROM (SELECT FULLNAME , ROW_NUMBER () OVER (ORDER BY FULLNAME) rn,
                       COUNT (*) OVER () cnt
                  FROM Table2)
         WHERE rn = cnt START WITH rn = 1 CONNECT BY rn = PRIOR rn + 1))

regexp_like中的子查询将列转换为包含正则表达式字符串的单个单元格。

我确实意识到这可能是一个性能杀手,但幸运的是,我现在并不是那个关于性能的讨论