一起使用SQL LIKE和IN
有没有办法一起使用LIKE和IN?
我想实现这样的事情。
SELECT * FROM tablename WHERE column IN ('M510%', 'M615%', 'M515%', 'M612%');
所以基本上我想能够匹配列与一堆不同的string。 是否有另一种方法来做到这一点与一个查询,或者我将不得不遍历我正在寻找的string数组?
你可以通过在一个查询中通过将各个LIKE与ORs串起来来完成它:
SELECT * FROM tablename WHERE column LIKE 'M510%' OR column LIKE 'M615%' OR column LIKE 'M515%' OR column LIKE 'M612%';
只要意识到像LIKE和每行函数这样的东西并不总是很好地扩展。 如果您的表可能会变大,您可能需要考虑在表中添加另一列来独立存储该字段的前四个字符。
这会复制数据,但可以保证使用插入和更新触发器保持一致。 然后把一个索引放在这个新列上,你的查询变成:
SELECT * FROM tablename WHERE newcolumn IN ('M510','M615','M515','M612');
这会将计算成本转移到必要的地方(数据发生变化时), 而不是每一次读取它。 事实上,你可以走得更远,把你的新列作为一个布尔值来表明它是四种特殊types之一(如果这组特殊的将不经常改变)。 那么查询会更快:
SELECT * FROM tablename WHERE is_special = 1;
存储对速度要求的权衡是大型数据库的一个有用的技巧 – 一般来说,磁盘空间便宜,CPU咕噜声是宝贵的,并且数据的读取次数比写入的要多得多。 通过将计算成本转移到写入阶段,您可以摊销所有读取的成本。
如何使用IN的子string。
select * from tablename where substring(column,1,4) IN ('M510','M615','M515','M612')
您将需要使用多个LIKE
术语,由OR
join。
使用更长的版本,这是一堆或。
SELECT * FROM tablename WHERE column LIKE 'M510%' OR column LIKE 'M615%' OR column LIKE 'M515%' OR column LIKE 'M612%';
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')
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%' )
我尝试了另一种方式
说表格有价值
1 M510 2 M615 3 M515 4 M612 5 M510MM 6 M615NN 7 M515OO 8 M612PP 9 A 10 B 11 C 12 D
这里第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函数,我试图find与任何值作为input表匹配的值。 如果是这样,它会返回它的索引,即大于零。 如果表格的值与任何input都不匹配,那么它将返回零。 我把这个索引加起来,表示成功匹配。
它似乎在工作。
希望能帮助到你。
您可以使用通配符的子查询:
SELECT 'Valid Expression' WHERE 'Source Column' LIKE (SELECT '%Column' --FROM TABLE)
或者你可以使用一个string:
SELECT 'Valid Expression' WHERE 'Source Column' LIKE ('%Source%' + '%Column%')
你甚至可以试试这个
function
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+'%';
对于完美的dynamic解决scheme,这可以通过组合游标和临时表来实现。 有了这个解决scheme,您不需要知道起始位置和长度,并且可以扩展,而无需在您的SQL查询中添加任何OR。
对于这个例子,假设你想从一个表格中select一个表格的详细信息和创builddate,其中一个文本列表在“Details”里面。
首先在一个名为Search的列中创build一个带有searchstring的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
希望这有助于