【问题标题】:Can the "IN" operator use LIKE-wildcards (%) in Oracle?“IN”运算符可以在 Oracle 中使用 LIKE 通配符 (%) 吗?
【发布时间】:2012-03-21 08:34:12
【问题描述】:

我已经搜索了这个问题,并在 MySQL 中找到了答案,但这是语句无法跨入 Oracle 的事件之一。

Can I use wildcards in "IN" MySQL statement?
几乎总结了我的问题和我想做的事情,但是在 Oracle 中

我想找到合法的等价物

Select * from myTable m
where m.status not in ('Done%', 'Finished except%', 'In Progress%')

感谢您的帮助

【问题讨论】:

    标签: sql oracle where wildcard


    【解决方案1】:
    Select * from myTable m
    where m.status not like 'Done%' 
    and m.status not like 'Finished except%'
    and m.status not like 'In Progress%'
    

    【讨论】:

    • 我试图避开漫长的路线,但看起来这可能是唯一的方法
    • @Matt 如果这只是写稍微短一点的 SQL 文本,那么不要只使用这个答案中提出的语法并学习它。如果这是关于 LIKEing 另一个表中的行(因此您不能真正提前构造值列表),那么这完全是一个不同的问题,需要类似:JOIN OTHER_TABLE ON NOT (YOUR_TABLE.FIELD LIKE OTHER_TABLE.FIELD)...
    • 为了简单起见,我最终使用了这个,但正则表达式的答案对于学习 Oracle 的新知识很有帮助。谢谢大家
    【解决方案2】:

    看来你也可以用正则表达式

    WHERE NOT REGEXP_LIKE(field, '^Done|^Finished')

    我不确定它的性能如何......请参阅here

    【讨论】:

      【解决方案3】:

      这似乎符合您的要求:https://forums.oracle.com/forums/thread.jspa?threadID=2140801

      基本上,您需要使用正则表达式,因为 oracle 中似乎没有为此内置任何内容。

      我从线程中提取了示例并将其转换为您的目的。不过,我很讨厌正则表达式,所以可能需要调整:)

      SELECT  *
      FROM myTable m
      WHERE NOT regexp_like(m.status,'((Done^|Finished except^|In Progress^)')
      

      【讨论】:

        【解决方案4】:

        不是 100% 你在寻找什么,而是一种由内而外的方式:

        SQL> CREATE TABLE mytable (id NUMBER, status VARCHAR2(50));
        
        Table created.
        
        SQL> INSERT INTO mytable VALUES (1,'Finished except pouring water on witch');
        
        1 row created.
        
        SQL> INSERT INTO mytable VALUES (2,'Finished except clicking ruby-slipper heels');
        
        1 row created.
        
        SQL> INSERT INTO mytable VALUES (3,'You shall (not?) pass');
        
        1 row created.
        
        SQL> INSERT INTO mytable VALUES (4,'Done');
        
        1 row created.
        
        SQL> INSERT INTO mytable VALUES (5,'Done with it.');
        
        1 row created.
        
        SQL> INSERT INTO mytable VALUES (6,'In Progress');
        
        1 row created.
        
        SQL> INSERT INTO mytable VALUES (7,'In progress, OK?');
        
        1 row created.
        
        SQL> INSERT INTO mytable VALUES (8,'In Progress Check Back In Three Days'' Time');
        
        1 row created.
        
        SQL> SELECT *
          2  FROM   mytable m
          3  WHERE  +1 NOT IN (INSTR(m.status,'Done')
          4            ,       INSTR(m.status,'Finished except')
          5            ,       INSTR(m.status,'In Progress'));
        
                ID STATUS
        ---------- --------------------------------------------------
                 3 You shall (not?) pass
                 7 In progress, OK?
        
        SQL>
        

        【讨论】:

          【解决方案5】:

          有点复杂,但是:

          Select * from myTable m
          join (SELECT a.COLUMN_VALUE || b.COLUMN_VALUE status
          FROM   (TABLE(Sys.Dbms_Debug_Vc2coll('Done', 'Finished except', 'In Progress'))) a
          JOIN (Select '%' COLUMN_VALUE from dual) b on 1=1) params
          on params.status like m.status;
          

          这是一个非常独特的问题的解决方案,但它可能对某人有所帮助。本质上没有“in like”语句,也没有办法为列的第一个 variable_n 字符获取索引,所以我这样做是为了在 SSRS 中使用快速动态的“in like”。

          列表内容('Done'、'Finished except'、'In Progress')可以是可变的。

          【讨论】:

          • 这是非常有价值的答案,因为它可以很好地适应多种模式。我的用例是在字符串中搜索,所以我在自己的答案中推出了类似但有点简化的解决方案。
          【解决方案6】:

          与所讨论的非法语法最接近的合法等价物是:

          select * from myTable m
          where not exists (
            select 1
            from table(sys.ku$_vcnt('Done', 'Finished except', 'In Progress')) patterns
            where m.status like patterns.column_value || '%'
          )
          

          我的和@Sethionic 的答案都可以动态列出模式(只需选择辅助sys.whatever 表以外的其他来源)。

          注意,如果我们必须搜索模式 inside 字符串(而不是从头开始)和包含例如 status = 'Done In Progress' 的数据库,那么 我的解决方案(修改为like '%' || patterns.column_value || '%')仍会为给定记录生成一行,而 @Sethionic 的解决方案(在 a 之前修改为另一个辅助连接)将为每个模式出现生成多行。 不判断哪个更好,只需了解差异并选择更适合您的需求。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-10-24
            • 2013-02-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-08-30
            相关资源
            最近更新 更多