Is there a combination of "LIKE" and "IN" in SQL?
Asked Answered
K

29

455

In SQL I (sadly) often have to use "LIKE" conditions due to databases that violate nearly every rule of normalization. I can't change that right now. But that's irrelevant to the question.

Further, I often use conditions like WHERE something in (1,1,2,3,5,8,13,21) for better readability and flexibility of my SQL statements.

Is there any possible way to combine these two things without writing complicated sub-selects?

I want something as easy as WHERE something LIKE ('bla%', '%foo%', 'batz%') instead of this:

WHERE something LIKE 'bla%'
OR something LIKE '%foo%'
OR something LIKE 'batz%'

I'm working with SQl Server and Oracle here but I'm interested if this is possible in any RDBMS at all.

Karisakarissa answered 10/6, 2010 at 13:44 Comment(5)
You have to do and like or: AND (something LIKE '%thing%' or something LIKE '%thing%' or something LIKE '%thing%')Toboggan
I wish we had Teradata's like any/like all: https://mcmap.net/q/81494/-sql-like-any-vs-like-all. (For the record, this has been requested on the Oracle Community Ideas forum community.oracle.com/ideas/11592)Panettone
similar https://mcmap.net/q/81495/-sql-server-using-wildcard-within-in/125981Violoncellist
Snowflake also supports LIKE ANY docs.snowflake.com/en/sql-reference/functions/like_any.htmlMandelbaum
MySQL - REGEXP - See #9099969Agni
U
247

There is no combination of LIKE & IN in SQL, much less in TSQL (SQL Server) or PLSQL (Oracle). Part of the reason for that is because Full Text Search (FTS) is the recommended alternative.

Both Oracle and SQL Server FTS implementations support the CONTAINS keyword, but the syntax is still slightly different:

Oracle:

WHERE CONTAINS(t.something, 'bla OR foo OR batz', 1) > 0

SQL Server:

WHERE CONTAINS(t.something, '"bla*" OR "foo*" OR "batz*"')

The column you are querying must be full-text indexed.

Reference:

Unbidden answered 10/6, 2010 at 17:34 Comment(3)
Hi, with Oracle, you need to build plaintext indexes on the columns you want to apply "CONTAINS" operator. Depending of your data volume this could be quite long.Semmes
With SQL Server (at least the 2008 version) the comment of @Pilooz does apply too, you need to build full text indexes.Princess
Maximum length is 4000.Cycloid
N
76

If you want to make your statement easily readable, then you can use REGEXP_LIKE (available from Oracle version 10 onwards).

An example table:

SQL> create table mytable (something)
  2  as
  3  select 'blabla' from dual union all
  4  select 'notbla' from dual union all
  5  select 'ofooof' from dual union all
  6  select 'ofofof' from dual union all
  7  select 'batzzz' from dual
  8  /

Table created.

The original syntax:

SQL> select something
  2    from mytable
  3   where something like 'bla%'
  4      or something like '%foo%'
  5      or something like 'batz%'
  6  /

SOMETH
------
blabla
ofooof
batzzz

3 rows selected.

And a simple looking query with REGEXP_LIKE

SQL> select something
  2    from mytable
  3   where regexp_like (something,'^bla|foo|^batz')
  4  /

SOMETH
------
blabla
ofooof
batzzz

3 rows selected.

BUT ...

I would not recommend it myself due to the not-so-good performance. I'd stick with the several LIKE predicates. So the examples were just for fun.

Nullify answered 10/6, 2010 at 14:19 Comment(2)
+1 nice illustration of REGEXP usage in 10g. I'm curious, though, if performance would really be all that much worse. Both will require full table and/or index scans, no?Revolution
True. But regular expressions burn CPU like crazy, not I/O. If it is worse and how much worse it is, depends on how large your list of expressions is and whether the column is indexed or not, among others. It is just a warning, so that the original poster is not surprised when he starts implementing it.Nullify
W
66

you're stuck with the

WHERE something LIKE 'bla%'
OR something LIKE '%foo%'
OR something LIKE 'batz%'

unless you populate a temp table (include the wild cards in with the data) and join like this:

FROM YourTable                y
    INNER JOIN YourTempTable  t On y.something LIKE t.something

try it out (using SQL Server syntax):

declare @x table (x varchar(10))
declare @y table (y varchar(10))

insert @x values ('abcdefg')
insert @x values ('abc')
insert @x values ('mnop')

insert @y values ('%abc%')
insert @y values ('%b%')

select distinct *
FROM @x x
WHERE x.x LIKE '%abc%' 
   or x.x LIKE '%b%'


select distinct x.*  
FROM @x             x
    INNER JOIN  @y  y On x.x LIKE y.y

OUTPUT:

x
----------
abcdefg
abc

(2 row(s) affected)

x
----------
abc
abcdefg

(2 row(s) affected)
Wicklund answered 10/6, 2010 at 13:48 Comment(12)
Ok, this would work, but it's not going into my intended direction of making the SQL statement more easily readable :)Karisakarissa
in SQL you go for index usage and performance. Only use indenting and naming for SQL readability, when you make other modifications for readability only you risk changing the execution plan ( which affects index usage and performance). If you are not careful, you can easily change an instantly running query to a very slow one by making trivial changes.Wicklund
The first statement of this answer is key -- (most?) SQL-based systems and languages don't support what you want, not without implementing work-arounds. (In SQL server, would Full Text indexing help?)Apollonian
@Philip Kelley, can SQL Server's Full Text indexing do LIKE 'bla%' , which in the OP's example code? or can in only do LIKE '%bla%' searches?Wicklund
I honestly don't know, I've never used FT indexing. I tossed it in as a sample of a possible work-around that's already included in the product. For what he's doing (A or B or C), I suspect it doesn't do it, am fairly confident that it'd take a lot of effort to determine this, and know that its outside the scope of his original question (does SQL do it natively).Apollonian
+1 for joining to table, but don't use temp, just derive it (select A union all select B... )Morganstein
The inner join and like is a nice trick, I've used inner join sometable st on st.column like '%' + t.othercolumn + '%'Sphygmograph
Inner join will duplicate rows that match many conditions at once.Ravens
@Ravens that's what the "distinct" key word is for, eliminating duplicates. This really is the finest SQL oriented solution to the problem. Putting the list of possible matches in a temporary table is nice because you can fill it using different conditions. This is a dynamic approach, just like it is supposed to be.Wb
@AntoinePelletier using EXISTS instead of INNER JOIN would eliminate the need for the extra distinctRavens
@Ravens Yes it's another good, maybe better way. Just saw your answer and, it could be improved a bit. It appears non-dynamical and that's the only reason why it didn't receive my attention. Like you said in the comments, unions could be replaced by a temporary table. But it's nice to see it. If your request was complete (including the first SELECT) and used a dynamic approach (temp table) I would certainly upvote it and maybe consider it the best answer...Wb
The INNER JOIN with LIKE is a neat approach. Thanks .. works well!Ress
H
26

With PostgreSQL there is the ANY or ALL form:

WHERE col LIKE ANY( subselect )

or

WHERE col LIKE ALL( subselect )

where the subselect returns exactly one column of data.

Haswell answered 21/4, 2011 at 9:17 Comment(4)
Are LIKE ANY and LIKE ALL common to all SQL dialects, i.e. part of the core language, or specific to a dialect?Katzenjammer
@AssadEbrahim, no they are specific. Oracle has = ANY or <> ALL but it works only in SQL, not in PLSQL for example.Haswell
I think this is standard syntax (but not many DBMS have implemented it)Catechin
For postgres see #2246036Stomatal
R
20

Another solution, should work on any RDBMS:

WHERE EXISTS (SELECT 1
                FROM (SELECT 'bla%' pattern FROM dual UNION ALL
                      SELECT '%foo%'        FROM dual UNION ALL
                      SELECT 'batz%'        FROM dual)
               WHERE something LIKE pattern)

The inner select can be replaced by another source of patterns like a table (or a view) in this way:

WHERE EXISTS (SELECT 1
                FROM table_of_patterns t
               WHERE something LIKE t.pattern)

table_of_patterns should contain at least a column pattern, and can be populated like this:

INSERT INTO table_of_patterns(pattern) VALUES ('bla%');
INSERT INTO table_of_patterns(pattern) VALUES ('%foo%');
INSERT INTO table_of_patterns(pattern) VALUES ('batz%');
Ravens answered 18/10, 2016 at 9:54 Comment(2)
But it's uglier than a set of OR statementsCloying
@Fandango68, but the union of selects can be replaced by another source of patterns like a table, a view, etc.Ravens
C
11

I would suggest using a TableValue user function if you'd like to encapsulate the Inner Join or temp table techniques shown above. This would allow it to read a bit more clearly.

After using the split function defined at: http://www.logiclabz.com/sql-server/split-function-in-sql-server-to-break-comma-separated-strings-into-table.aspx

we can write the following based on a table I created called "Fish" (int id, varchar(50) Name)

SELECT Fish.* from Fish 
    JOIN dbo.Split('%ass,%e%',',') as Splits 
    on Name like Splits.items  //items is the name of the output column from the split function.

Outputs

1   Bass
2   Pike
7   Angler
8   Walleye
Cryptoanalysis answered 10/6, 2010 at 17:18 Comment(1)
A row will be duplicated if matched by many conditions at once.Ravens
R
11

I'm working with SQl Server and Oracle here but I'm interested if this is possible in any RDBMS at all.

Teradata supports LIKE ALL/ANY syntax:

ALL every string in the list.
ANY any string in the list.

┌──────────────────────────────┬────────────────────────────────────┐
│      THIS expression …       │ IS equivalent to this expression … │
├──────────────────────────────┼────────────────────────────────────┤
│ x LIKE ALL ('A%','%B','%C%') │ x LIKE 'A%'                        │
│                              │ AND x LIKE '%B'                    │
│                              │ AND x LIKE '%C%'                   │
│                              │                                    │
│ x LIKE ANY ('A%','%B','%C%') │ x LIKE 'A%'                        │
│                              │ OR x LIKE '%B'                     │
│                              │ OR x LIKE '%C%'                    │
└──────────────────────────────┴────────────────────────────────────┘

EDIT:

jOOQ version 3.12.0 supports that syntax:

Add synthetic [NOT] LIKE ANY and [NOT] LIKE ALL operators

A lot of times, SQL users would like to be able to combine LIKE and IN predicates, as in:

SELECT *
FROM customer
WHERE last_name [ NOT ] LIKE ANY ('A%', 'E%') [ ESCAPE '!' ]

The workaround is to manually expand the predicate to the equivalent

SELECT *
FROM customer
WHERE last_name LIKE 'A%'
OR last_name LIKE 'E%'

jOOQ could support such a synthetic predicate out of the box.


PostgreSQL LIKE/ILIKE ANY (ARRAY[]):

SELECT *
FROM t
WHERE c LIKE ANY (ARRAY['A%', '%B']);

SELECT *
FROM t
WHERE c LIKE ANY ('{"Do%", "%at"}');

db<>fiddle demo


Snowflake also supports LIKE ANY/LIKE ALL matching:

LIKE ANY/ALL

Allows case-sensitive matching of strings based on comparison with one or more patterns.

<subject> LIKE ANY (<pattern1> [, <pattern2> ... ] ) [ ESCAPE <escape_char> ]

Example:

SELECT * 
FROM like_example 
WHERE subject LIKE ANY ('%Jo%oe%','T%e')
-- WHERE subject LIKE ALL ('%Jo%oe%','J%e')
Rockabilly answered 10/9, 2018 at 20:20 Comment(0)
E
8

Use an inner join instead:

SELECT ...
FROM SomeTable
JOIN
(SELECT 'bla%' AS Pattern 
UNION ALL SELECT '%foo%'
UNION ALL SELECT 'batz%'
UNION ALL SELECT 'abc'
) AS Patterns
ON SomeTable.SomeColumn LIKE Patterns.Pattern
Equality answered 10/6, 2010 at 16:35 Comment(3)
Well, that's exactly what I'd like to avoid. Although it works.Karisakarissa
Why avoid this solution? It works as fast as the accepted solution, and is just as versatile.Soporific
@PhilFactor This solution can create duplicate rows.Agan
A
7

One approach would be to store the conditions in a temp table (or table variable in SQL Server) and join to that like this:

SELECT t.SomeField
FROM YourTable t
   JOIN #TempTableWithConditions c ON t.something LIKE c.ConditionValue
Amargo answered 10/6, 2010 at 13:48 Comment(1)
A row will be duplicated if matched by many conditions at once.Ravens
R
6

Starting with 2016, SQL Server includes a STRING_SPLIT function. I'm using SQL Server v17.4 and I got this to work for me:

DECLARE @dashboard nvarchar(50)
SET @dashboard = 'P1%,P7%'

SELECT * from Project p
JOIN STRING_SPLIT(@dashboard, ',') AS sp ON p.ProjectNumber LIKE sp.value
Rejoice answered 7/6, 2018 at 20:33 Comment(1)
Should really use where exists (select 1 from STRING_SPLIT(...) sp(value) where p.ProjectNumber LIKE sp.value) ) Using a join will return multiple rows if multiple patterns match.Chaney
C
5

u can even try this

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

Query

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+'%';
Ceballos answered 23/4, 2015 at 11:37 Comment(1)
I like this but you should use WHERE EXISTS rather than inner join. Inner join may return multiple rows where multiple patterns match.Chaney
C
5

I have a simple solution, that works in postgresql at least, using like any followed by the list of regex. Here is an example, looking at identifying some antibiotics in a list:

select *
from database.table
where lower(drug_name) like any ('{%cillin%,%cyclin%,%xacin%,%mycine%,%cephal%}')
Clung answered 28/12, 2016 at 19:13 Comment(0)
K
5

May be you think the combination like this:

SELECT  * 
FROM    table t INNER JOIN
(
  SELECT * FROM (VALUES('bla'),('foo'),('batz')) AS list(col)
) l ON t.column  LIKE '%'+l.Col+'%'

If you have defined full text index for your target table then you may use this alternative:

SELECT  * 
FROM    table t
WHERE CONTAINS(t.column, '"bla*" OR "foo*" OR "batz*"')
Kingbolt answered 17/6, 2019 at 7:34 Comment(2)
Thank you. This should be the accepted answer IMO. Not everyone has a defined full text index (whatever that means) Your first suggestions works like a charm. You can even put the wildcards in the temp table values itself instead of concatenating on the LIKE.Valentin
In the event anyone is interested here is an example of syntax to add additional columns when using VALUES: SELECT a, b FROM (VALUES (1, 2), (3, 4), (5, 6), (7, 8), (9, 10) ) AS MyTable(a, b);Mccutchen
B
3

I may have a solution for this, although it will only work in SQL Server 2008 as far as I know. I discovered that you can use the row-constructor described in https://mcmap.net/q/81498/-how-can-i-select-from-list-of-values-in-sql-server to join a 'fictional' table using a like clause. It sounds more complex then it is, look:

SELECT [name]
  ,[userID]
  ,[name]
  ,[town]
  ,[email]
FROM usr
join (values ('hotmail'),('gmail'),('live')) as myTable(myColumn) on email like '%'+myTable.myColumn+'%' 

This will result in all users with an e-mail adres like the ones provided in the list. Hope it's of use to anyone. The problem had been bothering me a while.

Begun answered 21/8, 2013 at 12:43 Comment(1)
That's interesting. However, be aware that this should only be used on a smal table as the like statement can't use indexes. This is why the full text search, while harder to intially set up, is the better choice if you have alot of data.Unilocular
T
3

I was also wondering for something like that. I just tested using a combination of SUBSTRING and IN and it is an effective solution for this kind of problem. Try the below query :

Select * from TB_YOUR T1 Where SUBSTRING(T1.Something, 1,3) IN ('bla', 'foo', 'batz')
Threedecker answered 19/2, 2016 at 20:39 Comment(2)
one issue with this approach is you loose the ability to use an index on t1.something if it exists..Nobleminded
this will never find 'batz'Ravens
R
3

In Oracle you can use a collection in the following way:

WHERE EXISTS (SELECT 1
                FROM TABLE(ku$_vcnt('bla%', '%foo%', 'batz%'))
               WHERE something LIKE column_value)

Here I have used a predefined collection type ku$_vcnt, but you can declare your own one like this:

CREATE TYPE my_collection AS TABLE OF VARCHAR2(4000);
Ravens answered 16/5, 2016 at 14:48 Comment(0)
S
1

If you are using MySQL the closest you can get is full-text search:

Full-Text Search, MySQL Documentation

Springclean answered 10/6, 2010 at 13:44 Comment(0)
S
1

This works for comma separated values

DECLARE @ARC_CHECKNUM VARCHAR(MAX)
SET @ARC_CHECKNUM = 'ABC,135,MED,ASFSDFSF,AXX'
SELECT ' AND (a.arc_checknum LIKE ''%' + REPLACE(@arc_checknum,',','%'' OR a.arc_checknum LIKE ''%') + '%'')''

Evaluates to:

 AND (a.arc_checknum LIKE '%ABC%' OR a.arc_checknum LIKE '%135%' OR a.arc_checknum LIKE '%MED%' OR a.arc_checknum LIKE '%ASFSDFSF%' OR a.arc_checknum LIKE '%AXX%')

If you want it to use indexes, you must omit the first '%' character.

Stavros answered 19/8, 2014 at 12:41 Comment(0)
E
1

For Sql Server you can resort to Dynamic SQL.

Most of the time in such situations you have the parameter of IN clause based on some data from database.

The example below is a little "forced", but this can match various real cases found in legacy databases.

Suppose you have table Persons where person names are stored in a single field PersonName as FirstName + ' ' + LastName. You need to select all persons from a list of first names, stored in field NameToSelect in table NamesToSelect, plus some additional criteria (like filtered on gender, birth date, etc)

You can do it as follows

-- @gender is nchar(1), @birthDate is date 

declare 
  @sql nvarchar(MAX),
  @subWhere nvarchar(MAX)
  @params nvarchar(MAX)

-- prepare the where sub-clause to cover LIKE IN (...)
-- it will actually generate where clause PersonName Like 'param1%' or PersonName Like 'param2%' or ...   
set @subWhere = STUFF(
  (
    SELECT ' OR PersonName like ''' + [NameToSelect] + '%''' 
        FROM [NamesToSelect] t FOR XML PATH('')
  ), 1, 4, '')

-- create the dynamic SQL
set @sql ='select 
      PersonName
      ,Gender
      ,BirstDate    -- and other field here         
  from [Persons]
  where 
    Gender = @gender
    AND BirthDate = @birthDate
    AND (' + @subWhere + ')'

set @params = ' @gender nchar(1),
  @birthDate Date'     

EXECUTE sp_executesql @sql, @params,    
  @gender,  
  @birthDate
Entebbe answered 15/6, 2015 at 14:42 Comment(0)
S
1

In Oracle RBDMS you can achieve this behavior using REGEXP_LIKE function.

The following code will test if the string three is present in the list expression one|two|three|four|five (in which the pipe "|" symbol means OR logic operation).

SELECT 'Success !!!' result
FROM dual
WHERE REGEXP_LIKE('three', 'one|two|three|four|five');

RESULT
---------------------------------
Success !!!

1 row selected.

Preceding expression is equivalent to:

three=one OR three=two OR three=three OR three=four OR three=five

So it will succeed.

On the other hand, the following test will fail.

SELECT 'Success !!!' result
FROM dual
WHERE REGEXP_LIKE('ten', 'one|two|three|four|five');

no rows selected

There are several functions related to regular expressions (REGEXP_*) available in Oracle since 10g version. If you are an Oracle developer and interested this topic this should be a good beginning Using Regular Expressions with Oracle Database.

Sustentacular answered 26/12, 2016 at 19:49 Comment(0)
D
0

No answer like this:

SELECT * FROM table WHERE something LIKE ('bla% %foo% batz%')

In oracle no problem.

Disembarrass answered 20/11, 2017 at 5:35 Comment(0)
M
0

In Teradata you can use LIKE ANY ('%ABC%','%PQR%','%XYZ%'). Below is an example which has produced the same results for me

--===========
--  CHECK ONE
--===========
SELECT *
FROM Random_Table A
WHERE (Lower(A.TRAN_1_DSC) LIKE ('%american%express%centurion%bank%')
OR Lower(A.TRAN_1_DSC) LIKE ('%bofi%federal%bank%')
OR Lower(A.TRAN_1_DSC) LIKE ('%american%express%bank%fsb%'))

;
--===========
--  CHECK TWO
--===========
SELECT *
FROM Random_Table  A
WHERE Lower(A.TRAN_1_DSC) LIKE ANY 
('%american%express%centurion%bank%',
'%bofi%federal%bank%',
'%american%express%bank%fsb%')
Mosstrooper answered 4/12, 2018 at 16:35 Comment(0)
H
0

Sorry for dredging up an old post, but it has a lot of views. I faced a similar problem this week and came up with this pattern:

declare @example table ( sampletext varchar( 50 ) );

insert @example values 
( 'The quick brown fox jumped over the lazy dog.' ),
( 'Ask not what your country can do for you.' ),
( 'Cupcakes are the new hotness.' );

declare @filter table ( searchtext varchar( 50 ) );

insert @filter values
( 'lazy' ),
( 'hotness' ),
( 'cupcakes' );

-- Expect to get rows 1 and 3, but no duplication from Cupcakes and Hotness
select * 
from @example e
where exists ( select * from @filter f where e.sampletext like '%' + searchtext + '%' )

Exists() works a little better than join, IMO, because it just tests each record in the set, but doesn't cause duplication if there are multiple matches.

Herbie answered 7/8, 2020 at 20:4 Comment(0)
I
0

This is possible in Postgres using like or ilike and any or all with array. This is an example that worked for me using Postgres 9:

select id, name from tb_organisation where name ilike any (array['%wembley%', '%south%']);

And this prints out:

 id  |          name
-----+------------------------
 433 | South Tampa Center
 613 | South Pole
 365 | Bromley South
 796 | Wembley Special Events
 202 | Southall
 111 | Wembley Inner Space
Irmine answered 6/4, 2022 at 7:2 Comment(0)
A
0

In T-SQL, this option works but it is not very fast:

CREATE FUNCTION FN_LIKE_IN (@PROC NVARCHAR(MAX), @ITENS NVARCHAR(MAX)) RETURNS NVARCHAR(MAX) AS BEGIN
    
        --Search an item with LIKE inside a list delimited by "," Vathaire 11/06/2019
    
    DECLARE @ITEM NVARCHAR(MAX)
    WHILE CHARINDEX(',', @ITENS) > 0 BEGIN
        SET @ITEM = LEFT(@ITENS, CHARINDEX(',', @ITENS) - 1)
        --IF @ITEM LIKE @PROC
        IF @PROC LIKE @ITEM
            RETURN @PROC --@ITEM --1
        ELSE
            SET @ITENS = STUFF(@ITENS, 1, LEN(@ITEM) + 1, '')
    END
    IF @PROC LIKE @ITENS RETURN @PROC --@ITEM --1
    RETURN NULL --0
END

Query:

SELECT * FROM SYS.PROCEDURES
WHERE DBO.FN_LIKE_IN(NAME, 'PRC%,SP%') IS NOT NULL
Annunciata answered 27/7, 2022 at 22:34 Comment(0)
K
0

you can do this dynamically for a large number of elements, at the expense of performance, but it works.

DECLARE @val nvarchar(256),
@list nvarchar(max) = 'one,two,three,ten,five';
CREATE table #table  (FIRST_NAME nvarchar(512), LAST_NAME nvarchar(512));
CREATE table #student  (FIRST_NAME nvarchar(512), LAST_NAME nvarchar(512), EMAIL 
nvarchar(512));
INSERT INTO #student (FIRST_NAME, LAST_NAME, EMAIL)
SELECT 'TEST', ' redOne' ,'[email protected]' UNION ALL
SELECT 'student', ' student' ,'[email protected]' UNION ALL
SELECT 'student', ' two' ,'[email protected]' UNION ALL
SELECT 'hello', ' ONE TWO THREE' ,'[email protected]'

DECLARE check_cursor CURSOR FOR select value from STRING_SPLIT(@list,',')

OPEN check_cursor  
FETCH NEXT FROM check_cursor INTO @val
WHILE @@FETCH_STATUS = 0  
    BEGIN
     PRINT @val
       IF EXISTS (select * from #student where REPLACE(FIRST_NAME, ' ','') 
like '%' + @val + '%' OR REPLACE(LAST_NAME, ' ','') like '%' + @val + '%') 
       BEGIN
       INSERT INTO #table (FIRST_NAME, LAST_NAME )
       SELECT TOP 1 FIRST_NAME, LAST_NAME VALUE from #student where 
REPLACE(FIRST_NAME, ' ','') like '%' + @val + '%' OR REPLACE(LAST_NAME, ' ','') 
like '%' + @val + '%'
       END;

      FETCH NEXT FROM check_cursor INTO @val 
    END
CLOSE check_cursor;  
DEALLOCATE check_cursor;  

SELECT * FROM #table;
DROP TABLE #table;
DROP TABLE #student;
Karlotta answered 27/10, 2022 at 10:25 Comment(0)
P
0

use cursor in SQL SERVER and execute for every value:

table sample:

 create table Gastos_ConciliacionExcluida(IdRegistro int identity(1,1), MascaraTexto nvarchar(50), Activa bit default 1, Primary key (IDRegistro))


insert into Gastos_ConciliacionExcluida(MascaraTexto) Values ('%Reembolso%')



alter procedure SP_Gastos_ConciliacionExcluidaProcesar
as

declare cur cursor for select MascaraTexto From Gastos_ConciliacionExcluida where Activa=1
declare @Txt nvarchar(50)

open cur

fetch next from cur into @Txt
while @@Fetch_Status = 0
begin
    update Gastos_BancoRegistro set PresumibleNoConciliable = 1 
    where   Concepto like @txt
    fetch next from cur into @Txt
end 
close cur
deallocate cur
Pistachio answered 1/12, 2022 at 16:16 Comment(0)
Z
-1

I hate to drag up this old topic, but I just had this problem in MySQL, and since I was building my statement in PHP, I was able to come up with a more efficient solution as far as coding is concerned.

First, I put everything I'm looking for into a simple array:

$myArray = ['bla%', '%foo%', 'batz%', 'bar%', '%cows', 'moo%'];

And then the magic happens when I build a cumbersome string with an implode statement:

if (sizeof($myArray) > 0) {
    $sqlLikes = "(Something LIKE '";
    $sqlLikes .= implode("' OR Something LIKE '", $myArray)
    $sqlLikes .= "')";
)

This builds a string that looks like this:

(Something LIKE 'bla%' OR Something LIKE '%foo%' OR Something LIKE 'batz%' OR Something LIKE 'bar%' OR Something LIKE '%cows' OR Something LIKE 'moo%')

And then I drop my string variable in my SQL statement as such:

$sql = <<<SQL
    SELECT * FROM FOOBAR
    WHERE $sqlLikes
SQL;

This will work for any size array. Yes, the resulting SQL statement will be cumbersome, but I don't care because I never need to see the statement, and building the sql was direct and simple for me.

Zebapda answered 6/1 at 17:16 Comment(0)
B
-3

do this

WHERE something + '%' in ('bla', 'foo', 'batz')
OR '%' + something + '%' in ('tra', 'la', 'la')

or

WHERE something + '%' in (select col from table where ....)
Briones answered 17/4, 2015 at 14:8 Comment(1)
How's that going to work? The LHS is a string with a %, and that % is therefore not a wildcardMaeganmaelstrom

© 2022 - 2024 — McMap. All rights reserved.