一起使用SQL LIKE和IN

时间:2010-02-23 12:42:20

标签: mysql

有没有办法一起使用LIKE和IN?

我想实现这样的目标。

SELECT * FROM tablename WHERE column IN ('M510%', 'M615%', 'M515%', 'M612%');

所以基本上我希望能够将列与一堆不同的字符串进行匹配。有没有其他方法可以使用一个查询执行此操作,还是我必须遍历我正在寻找的字符串数组?

10 个答案:

答案 0 :(得分:53)

如何在IN中使用子字符串。

select * from tablename where substring(column,1,4) IN ('M510','M615','M515','M612')

答案 1 :(得分:50)

您可以通过将单个LIKE与ORs串在一起来在一个查询中执行此操作:

SELECT * FROM tablename
WHERE column LIKE 'M510%'
OR    column LIKE 'M615%'
OR    column LIKE 'M515%'
OR    column LIKE 'M612%';

请注意,LIKE和per-row函数之类的东西并不总能很好地扩展。如果您的表格可能会变大,可能想要考虑在表格中添加另一列来独立存储该字段的前四个字符。

这会复制数据,但您可以通过使用插入和更新触发器来保证它保持一致。然后在该新列上添加索引,您的查询将变为:

SELECT * FROM tablename WHERE newcolumn IN ('M510','M615','M515','M612');

这会将计算成本转移到必要时(数据发生变化时),每次读取它。实际上,您可以更进一步,将新列作为布尔值,表明它是四种特殊类型之一(如果该组特殊值不经常更改)。然后查询会更快:

SELECT * FROM tablename WHERE is_special = 1;

对速度存储要求的这种折衷对于大型数据库来说是一个有用的技巧 - 通常,磁盘空间很便宜,CPU咕噜声很珍贵,而且数据读取的频率远远超过写入数据。通过将计算成本转移到写入阶段,您可以在所有读取中分摊成本。

答案 2 :(得分:8)

您需要使用LIKE加入的多个OR条款。

答案 3 :(得分:5)

使用较长版本的IN,这是一堆OR。

SELECT * FROM tablename 
WHERE column LIKE 'M510%'
OR column LIKE 'M615%'
OR column LIKE 'M515%'
OR column LIKE 'M612%';

答案 4 :(得分:2)

substr([column name],
       [desired starting position (numeric)],
       [# characters to include (numeric)]) in ([complete as usual])

实施例

substr([column name],1,4) in ('M510','M615', 'M515', 'M612')

答案 5 :(得分:2)

SELECT * FROM tablename
  WHERE column IN 
    (select column from  tablename 
    where column like 'M510%' 
    or column like 'M615%' 
    OR column like 'M515%' 
    or column like'M612%'
    )

答案 6 :(得分:1)

我尝试了另一种方式

假设表格有值


    1   M510
    2   M615
    3   M515
    4   M612
    5   M510MM
    6   M615NN
    7   M515OO
    8   M612PP
    9   A
    10  B
    11  C
    12  D

此处cols 1到8有效,而其余的无效


  SELECT COL_VAL
    FROM SO_LIKE_TABLE SLT
   WHERE (SELECT DECODE(SUM(CASE
                              WHEN INSTR(SLT.COL_VAL, COLUMN_VALUE) > 0 THEN
                               1
                              ELSE
                               0
                            END),
                        0,
                        'FALSE',
                        'TRUE')
            FROM TABLE(SYS.DBMS_DEBUG_VC2COLl('M510', 'M615', 'M515', 'M612'))) =
         'TRUE'

我所做的是使用INSTR函数,我试图找到表中的值与任何值匹配作为输入。如果是这样,它将返回它的索引,即大于零。如果表的值与任何输入不匹配,则它将返回ZERO。我加上这个索引,表示成功匹配。

似乎有效。

希望它有所帮助。

答案 7 :(得分:1)

您可以使用带通配符的子查询:

 SELECT 'Valid Expression'
 WHERE 'Source Column' LIKE (SELECT '%Column' --FROM TABLE)

或者您可以使用单个字符串:

 SELECT 'Valid Expression'
 WHERE 'Source Column' LIKE ('%Source%' + '%Column%')

答案 8 :(得分:1)

你甚至可以尝试这个

功能

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('M510', 'M615', 'M515', 'M612',','))
as split_table on my_table.column_name like '%'+split_table.value+'%';

答案 9 :(得分:0)

对于完美动态的解决方案,可以通过组合游标和临时表来实现。使用此解决方案,您无需知道起始位置和长度,并且可以扩展,而无需向SQL查询添加任何OR。

对于此示例,假设您要选择ID,详细信息和&从表中创建日期,其中某个文本列表位于“详细信息”中。

首先使用名为Search的列中的搜索字符串创建一个表FilterTable。

正如问题首发所要求的那样:

insert into [DATABASE].dbo.FilterTable
select 'M510' union
select 'M615' union
select 'M515' union 
select 'M612'

然后您可以按以下方式过滤数据:

DECLARE @DATA NVARCHAR(MAX)

CREATE TABLE #Result (ID uniqueIdentifier, Details nvarchar(MAX), Created datetime)

DECLARE DataCursor CURSOR local forward_only FOR  
SELECT '%' + Search + '%'
FROM [DATABASE].dbo.FilterTable

OPEN DataCursor   
FETCH NEXT FROM DataCursor INTO @DATA   

WHILE @@FETCH_STATUS = 0   
BEGIN   

    insert into #Result
        select ID, Details, Created
        from [DATABASE].dbo.Table (nolock)
        where Details like @DATA

   FETCH NEXT FROM DataCursor INTO @DATA   
END   

CLOSE DataCursor   
DEALLOCATE DataCursor 

select * from #Result
drop table #Result

希望这有帮助