【问题标题】:How can I introduce multiple conditions in LIKE operator?如何在 LIKE 运算符中引入多个条件?
【发布时间】:2010-11-26 03:13:49
【问题描述】:

我想写如下 SQL 语句:

select * from tbl where col like ('ABC%','XYZ%','PQR%');

我知道可以使用OR 来完成。但我想知道有没有更好的解决方案。

【问题讨论】:

  • OR 有什么问题?或者你有一组动态的条件?
  • OR 有什么问题?打字量?
  • 显然,我实时使用了 OR。但我想知道有没有其他方法可以替换 OR
  • 除了对 LIKE 谓词进行 OR'ing 之外,还有其他方法,但没有更好的方法。
  • 如果 SELECT 查询很大,做 UNION 只是浪费时间。或是最好的方法,足以帮助达到提出问题的目的。谢谢。

标签: sql oracle


【解决方案1】:

这是另一种方法:

select * from tbl where col like 'ABC%'
union
select * from tbl where col like 'XYZ%'
union
select * from tbl where col like 'PQR%';

这是要验证的测试代码:

create table tbl (col varchar(255));
insert into tbl (col) values ('ABCDEFG'), ('HIJKLMNO'), ('PQRSTUVW'), ('XYZ');
select * from tbl where col like 'ABC%'
union
select * from tbl where col like 'XYZ%'
union
select * from tbl where col like 'PQR%';
+----------+
| col      |
+----------+
| ABCDEFG  |
| XYZ      |
| PQRSTUVW |
+----------+
3 rows in set (0.00 sec)

【讨论】:

    【解决方案2】:

    这是临时表的一个很好的用途。

    CREATE TEMPORARY TABLE patterns (
      pattern VARCHAR(20)
    );
    
    INSERT INTO patterns VALUES ('ABC%'), ('XYZ%'), ('PQR%');
    
    SELECT t.* FROM tbl t JOIN patterns p ON (t.col LIKE p.pattern);
    

    在示例模式中,col 无法匹配多个模式,因此您可以确定在结果中最多会看到 tbl 的每一行。但是,如果您的模式使得 col 可以匹配多个,您应该使用 DISTINCT 查询修饰符。

    SELECT DISTINCT t.* FROM tbl t JOIN patterns p ON (t.col LIKE p.pattern);
    

    【讨论】:

    • 优秀。正是我需要从我的代码中删除硬编码的值。我的字符串掩码存储在配置表中。旧代码中的每一个都是硬编码的。这不是更改值的优雅解决方案,如果我有任何新值,则需要更改控制协议。我不知道你可以使用语法“ON (my_field LIKE my_mask)。谢谢。
    • 是的!您可以使用任何您想要的表达式作为连接条件。大多数人使用简单的相等比较,但这不是限制。
    【解决方案3】:

    这可能会有所帮助:

    select * from tbl where col like '[ABC-XYZ-PQR]%'
    

    我已经在 SQL Server 2005 中使用过它并且它有效。

    【讨论】:

    • 不会给出不相关的结果吗?
    • 这非常适合从数据集中提取部分匹配的代码,例如将字符附加到相同的基本代码以表示地理位置
    • 它没有提供所需的记录
    【解决方案4】:
    select * from tbl where col like 'ABC%'
    or col like 'XYZ%'
    or col like 'PQR%';
    

    这适用于 toad 和 powerbuilder。其他的就不知道了

    【讨论】:

    • 其实这就是OP使用的语法;他们想要那个表述的替代品
    • 也适用于 Oracle SQL 开发人员。
    【解决方案5】:

    Oracle 10g 具有允许在 SQL 中使用符合 POSIX 的正则表达式的功能:

    • REGEXP_LIKE
    • REGEXP_REPLACE
    • REGEXP_INSTR
    • REGEXP_SUBSTR

    有关此函数的语法详细信息,请参阅Oracle Database SQL Reference

    看看Regular expressions in Perl的例子。

    代码:

        select * from tbl where regexp_like(col, '^(ABC|XYZ|PQR)');
    

    【讨论】:

    • Oracle 当然可以为LIKE 'ABC%' 使用索引,但我不相信它可以使用索引进行正则表达式操作(除非它是基于函数的索引)
    • 这是最好的方法...感谢分享。这确实很有帮助,虽然这是一个旧帖子。
    【解决方案6】:

    我也有同样的要求,我没有选择通过执行 OR 或编写联合查询来多次传递 like 运算符。

    This worked for me in Oracle 11g:
    
    REGEXP_LIKE (column, 'ABC.*|XYZ.*|PQR.*'); 
    

    【讨论】:

      【解决方案7】:

      你也可以试试这个

      功能

      CREATE  FUNCTION [dbo].[fn_Split](@text varchar(8000), @delimiter varchar(20))
      RETURNS @Strings TABLE
      (   
        position int IDENTITY PRIMARY KEY,
        value varchar(8000)  
      )
      AS
      BEGIN
      
      DECLARE @index int
      SET @index = -1
      
      WHILE (LEN(@text) > 0)
        BEGIN 
          SET @index = CHARINDEX(@delimiter , @text) 
          IF (@index = 0) AND (LEN(@text) > 0) 
            BEGIN  
              INSERT INTO @Strings VALUES (@text)
                BREAK 
            END 
          IF (@index > 1) 
            BEGIN  
              INSERT INTO @Strings VALUES (LEFT(@text, @index - 1))  
              SET @text = RIGHT(@text, (LEN(@text) - @index)) 
            END 
          ELSE
            SET @text = RIGHT(@text, (LEN(@text) - @index))
          END
        RETURN
      END
      

      查询

      select * from my_table inner join (select value from fn_split('ABC,MOP',','))
      as split_table on my_table.column_name like '%'+split_table.value+'%';
      

      【讨论】:

        【解决方案8】:

        如果你的参数值不固定或者你的值根据业务可以为null,可以试试下面的方法。

        DECLARE @DrugClassstring VARCHAR(MAX);
        SET @DrugClassstring = 'C3,C2'; -- You can pass null also
        
        ---------------------------------------------
        
        IF @DrugClassstring IS NULL 
            SET @DrugClassstring = 'C3,C2,C4,C5,RX,OT'; -- If null you can set your all conditional case that will return for all
        SELECT dn.drugclass_FK , dn.cdrugname
        FROM drugname AS dn
        INNER JOIN dbo.SplitString(@DrugClassstring, ',') class ON dn.drugclass_FK = class.[Name] -- SplitString is a a function
        

        SplitString 函数

        SET ANSI_NULLS ON;
        GO
        SET QUOTED_IDENTIFIER ON;
        GO
        ALTER FUNCTION [dbo].[SplitString](@stringToSplit VARCHAR(MAX),
                                           @delimeter     CHAR(1)      = ',')
        RETURNS @returnList TABLE([Name] [NVARCHAR](500))
        AS
             BEGIN
        
                 --It's use in report sql, before any change concern to everyone
        
                 DECLARE @name NVARCHAR(255);
                 DECLARE @pos INT;
                 WHILE CHARINDEX(@delimeter, @stringToSplit) > 0
                     BEGIN
                         SELECT @pos = CHARINDEX(@delimeter, @stringToSplit);
                         SELECT @name = SUBSTRING(@stringToSplit, 1, @pos-1);
                         INSERT INTO @returnList
                                SELECT @name;
                         SELECT @stringToSplit = SUBSTRING(@stringToSplit, @pos+1, LEN(@stringToSplit)-@pos);
                     END;
                 INSERT INTO @returnList
                        SELECT @stringToSplit;
                 RETURN;
             END;
        

        【讨论】:

          【解决方案9】:

          选择 * 来自 tbl 哪里科尔 LIKE '[0-9,a-z]%';

          只需在sql中使用like这个条件,你就会得到你想要的答案

          【讨论】:

            【解决方案10】:

            我必须将 all 添加到 Asaph's answer 才能使其正常工作。

            select * from tbl where col like 'ABC%'
            union all
            select * from tbl where col like 'XYZ%'
            union all
            select * from tbl where col like 'PQR%';
            

            【讨论】:

              猜你喜欢
              • 2015-07-01
              • 1970-01-01
              • 2012-01-30
              • 1970-01-01
              • 2018-10-12
              • 1970-01-01
              • 2021-07-22
              • 1970-01-01
              相关资源
              最近更新 更多