如何在LIKE运算符中引入多个条件?


72

我想写一条如下的SQL语句:

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

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


2
OR有什么问题?还是您有一套动态的条件?
Tomas Aschan 09年

OR有什么问题?打字量?
马修·洛克

1
显然,我是实时使用OR的。但我想知道还有其他方法可以替代OR
Madhu

除了对LIKE谓词进行“或”运算外,还有其他方法,但是没有更好的方法。
杰弗里·肯普

2
如果SELECT查询很大,那么执行UNION只是浪费时间。OR是最好的方法,足以帮助解决所问问题的目的。谢谢。
国王

Answers:


45

这是另一种方法:

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)

61

这是临时表的好用法。

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)谢谢。
莎丽W¯¯

是的 您可以使用任何想要的表达式作为连接条件。大多数人使用简单的相等比较,但这不是限制。
Bill Karwin

46

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

  • REGEXP_LIKE
  • REGEXP_REPLACE
  • REGEXP_INSTR
  • REGEXP_SUBSTR

请参见《Oracle数据库SQL参考》此函数的语法详细信息,》。

看看Perl中的正则表达式使用示例。

代码:

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

1
Oracle当然可以使用索引,LIKE 'ABC%'但是我不认为它可以将索引用于REGEX操作(除非它是基于
函数

这是最好的方法...感谢您的分享。尽管这是一个过时的帖子,但确实很有帮助。
NIK

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

这适用于蟾蜍和powerbuilder。不知道其余的


3
实际上,这就是OP使用的语法;他们想要替代该提法。
APC 2012年

也可以在Oracle SQL Developer中使用。
Shams 2013年

6

这可能会有所帮助:

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

我在SQL Server 2005中使用了它,并且它起作用了。


6
它不会给出无关紧要的结果吗?
NileshChauhan

这非常适合从数据集中提取部分匹配的代码,例如将字符附加到同一基本代码以表示地理位置
Hilary

它没有提供所需的记录
Rajesh Om

4

我也有相同的要求,即我没有选择通过执行OR或编写并集查询来多次像运算符一样传递。

This worked for me in Oracle 11g:

REGEXP_LIKE (column, 'ABC.*|XYZ.*|PQR.*'); 

0

即使你可以尝试这个

功能

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+'%';

0

如果您的参数值不是固定的,或者您的值根据业务可能为空,则可以尝试以下方法。

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;

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.