Existe uma combinação de "LIKE" e "IN" no SQL?

340

No SQL I (infelizmente) muitas vezes é necessário usar LIKEcondições " " devido a bancos de dados que violam quase todas as regras de normalização. Não posso mudar isso agora. Mas isso é irrelevante para a questão.

Além disso, costumo usar condições como WHERE something in (1,1,2,3,5,8,13,21)para melhor legibilidade e flexibilidade de minhas instruções SQL.

Existe alguma maneira possível de combinar essas duas coisas sem escrever sub-seleções complicadas?

Eu quero algo tão fácil quanto, em WHERE something LIKE ('bla%', '%foo%', 'batz%')vez disso:

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

Estou trabalhando com o SQl Server e Oracle aqui, mas estou interessado se isso for possível em qualquer RDBMS.

selfawaresoup
fonte
11
Você tem que fazer e como ou: E (algo como '% coisa%' ou algo como '% coisa%' ou algo como '% coisa%')
Cosmic Falcão
Eu gostaria que tivéssemos like any/ do Teradata like all: stackoverflow.com/questions/40475982/sql-like-any-vs-like-all . (Para constar, isso foi solicitado no fórum Oracle Community Ideas community.oracle.com/ideas/11592 )
William Robertson

Respostas:

196

Não há combinação de LIKE & IN no SQL, muito menos no TSQL (SQL Server) ou PLSQL (Oracle). Parte do motivo disso é porque a Pesquisa de Texto Completo (STF) é a alternativa recomendada.

As implementações Oracle e SQL Server FTS suportam a palavra-chave CONTAINS, mas a sintaxe ainda é um pouco diferente:

Oráculo:

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

Servidor SQL:

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

A coluna que você está consultando deve ser indexada em texto completo.

Referência:

Pôneis OMG
fonte
11
Olá, com o Oracle, você precisa criar índices de texto sem formatação nas colunas nas quais deseja aplicar o operador "CONTAINS". Dependendo do volume de dados, isso pode ser bastante longo.
Pierre-Gilles Levallois
18
Com o SQL Server (pelo menos a versão de 2008), o comentário do @Pilooz também se aplica, você precisa criar índices de texto completo.
Marcel
O comprimento máximo é 4000.
14 ʙᴀᴋᴇʀ
59

Se você deseja tornar sua declaração facilmente legível, use REGEXP_LIKE (disponível a partir do Oracle versão 10).

Uma tabela de exemplo:

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.

A sintaxe original:

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.

E uma consulta simples com REGEXP_LIKE

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

SOMETH
------
blabla
ofooof
batzzz

3 rows selected.

MAS ...

Eu não recomendaria eu mesmo devido ao desempenho não tão bom. Eu ficaria com os vários predicados LIKE. Portanto, os exemplos foram apenas por diversão.

Rob van Wijk
fonte
4
Uma boa ilustração do uso do REGEXP em 10g. Estou curioso, no entanto, se o desempenho seria realmente muito pior. Ambos exigirão varreduras completas de tabela e / ou índice, não?
DCookie
12
Verdade. Mas expressões regulares queimam a CPU como loucas, não como E / S. Se é pior e quanto é pior, depende do tamanho da sua lista de expressões e se a coluna está indexada ou não, entre outras. É apenas um aviso, para que o pôster original não seja surpreendido quando ele começar a implementá-lo.
Rob van Wijk
49

você está preso com o

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

a menos que você preencha uma tabela temporária (inclua os curingas com os dados) e ingresse da seguinte maneira:

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

experimente (usando a sintaxe do SQL Server):

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

RESULTADO:

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

(2 row(s) affected)

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

(2 row(s) affected)
KM.
fonte
Ok, isso iria funcionar, mas ele não está indo para a minha direcção pretendida de fazer a instrução SQL mais facilmente legível :)
selfawaresoup
10
no SQL, você procura o uso e o desempenho do índice. Use apenas recuo e nomeação para facilitar a leitura do SQL; quando você fizer outras modificações para facilitar a leitura, corre o risco de alterar o plano de execução (que afeta o uso e o desempenho do índice). Se você não tomar cuidado, poderá alterar facilmente uma consulta em execução instantânea para uma consulta muito lenta, fazendo alterações triviais.
KM.
A primeira declaração desta resposta é fundamental - (a maioria?) Os sistemas e linguagens baseados em SQL não suportam o que você deseja, não sem implementar soluções alternativas. (Servidor Em SQL, seria indexação de texto completo ajuda?)
Philip Kelley
@ Phillip Kelley, pode a indexação de texto completo do SQL Server LIKE 'bla%' , que no código de exemplo do OP? ou só pode fazer LIKE '%bla%'pesquisas?
KM.
Sinceramente, não sei, nunca usei a indexação FT. Joguei-o como uma amostra de uma possível solução alternativa que já está incluída no produto. Pelo que ele está fazendo (A ou B ou C), suspeito que isso não ocorra, estou bastante confiante de que seria necessário muito esforço para determinar isso e sei que está fora do escopo de sua pergunta original (não SQL faça isso nativamente).
Philip Kelley
20

Com o PostgreSQL, existe o formulário ANYou ALL:

WHERE col LIKE ANY( subselect )

ou

WHERE col LIKE ALL( subselect )

onde a subseleção retorna exatamente uma coluna de dados.

Benoit
fonte
11
São LIKE ANYe LIKE ALLcomum a todos os dialetos SQL, ou seja, parte da linguagem do núcleo, ou específica para um dialeto?
Assad Ebrahim
11
@AssadEbrahim, não, eles são específicos. O Oracle possui = ANYou <> ALLfunciona apenas no SQL, não no PLSQL, por exemplo.
Benoit
Eu acho que esta é a sintaxe padrão (mas não muitos DBMS implementaram-lo)
ypercubeᵀᴹ
Para o postgres, veja stackoverflow.com/questions/2245536/…
rogerdpack
13

Outra solução, deve funcionar em qualquer 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)
mik
fonte
11
Mas é mais feio do que um conjunto de OR
Fandango68
11
@ Fandango68, mas a união de seleciona pode ser substituída por outra fonte de padrões como uma mesa, uma visão, etc.
mik
10

Sugiro que você use uma função de usuário TableValue se desejar encapsular as técnicas de junção interna ou de tabela temporária mostradas acima. Isso permitiria ler um pouco mais claramente.

Depois de usar a função de divisão definida em: http://www.logiclabz.com/sql-server/split-function-in-sql-server-to-break-comma-separated-strings-into-table.aspx

podemos escrever o seguinte com base em uma tabela que criei chamada "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.

Saídas

1 baixo
2 Pike
7 Pescador
8 Walleye
Nerd famoso
fonte
11
Uma linha será duplicada se corresponder a várias condições ao mesmo tempo.
Mik
7

Uma abordagem seria armazenar as condições em uma tabela temporária (ou variável de tabela no SQL Server) e ingressar nessa:

SELECT t.SomeField
FROM YourTable t
   JOIN #TempTableWithConditions c ON t.something LIKE c.ConditionValue
AdaTheDev
fonte
Uma linha será duplicada se corresponder a várias condições ao mesmo tempo.
Mik
7

Use uma junção interna:

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
AK
fonte
11
Bem, é exatamente isso que eu gostaria de evitar. Embora funcione.
precisa
Por que evitar esta solução? Funciona tão rápido quanto a solução aceita e é tão versátil.
Phil Factor
3
@PhilFactor Esta solução pode criar linhas duplicadas.
Jakub Kania
5

Estou trabalhando com o SQl Server e Oracle aqui, mas estou interessado se isso for possível em qualquer RDBMS.

O Teradata suporta a sintaxe de ALL / ANY :

TODAS todas as strings da lista.
QUALQUER qualquer sequência na lista.

┌──────────────────────────────┬────────────────────────────────────┐
      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%'                    
└──────────────────────────────┴────────────────────────────────────┘

EDITAR:

O jOOQ versão 3.12.0 suporta essa sintaxe:

Adicione operadores sintéticos [NOT] LIKE ANY e [NOT] LIKE ALL

Muitas vezes, os usuários do SQL gostariam de combinar os predicados LIKE e IN, como em:

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

A solução alternativa é expandir manualmente o predicado para o equivalente

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

O jOOQ poderia suportar esse predicado sintético imediatamente.


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 <> demo de violino


O Snowflake também suporta a correspondência LIY ANY / LIKE ALL :

COMO QUALQUER / TUDO

Permite a correspondência de seqüências que diferencia maiúsculas de minúsculas com base na comparação com um ou mais padrões.

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

Exemplo:

SELECT * 
FROM like_example 
WHERE subject LIKE ANY ('%Jo%oe%','T%e')
-- WHERE subject LIKE ALL ('%Jo%oe%','J%e')
Lukasz Szozda
fonte
4

você pode até tentar isso

Função

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

Inquerir

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+'%';
SimarjeetSingh Panghlia
fonte
4

Eu tenho uma solução simples, que funciona pelo menos no postgresql , usando like anyseguido pela lista de regex. Aqui está um exemplo, procurando identificar alguns antibióticos em uma lista:

select *
from database.table
where lower(drug_name) like any ('{%cillin%,%cyclin%,%xacin%,%mycine%,%cephal%}')
mkomo
fonte
3

Eu também estava pensando em algo assim. Eu apenas testada usando uma combinação de SUBSTRINGe INe é uma solução eficaz para este tipo de problema. Tente a consulta abaixo:

Select * from TB_YOUR T1 Where SUBSTRING(T1.Something, 1,3) IN ('bla', 'foo', 'batz')
ssah
fonte
11
Um problema com esta abordagem é que você solta a capacidade de usar um índice em t1.something se existir ..
cadarço
11
isso nunca vai encontrar 'Batz'
mik
3

No Oracle, você pode usar uma coleção da seguinte maneira:

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

Aqui, usei um tipo de coleção predefinido ku$_vcnt, mas você pode declarar o seu próprio como este:

CREATE TYPE my_collection AS TABLE OF VARCHAR2(4000);
mik
fonte
2

Para o Sql Server, você pode recorrer ao SQL dinâmico.

Na maioria das vezes, nessas situações, você tem o parâmetro da cláusula IN com base em alguns dados do banco de dados.

O exemplo abaixo é um pouco "forçado", mas isso pode corresponder a vários casos reais encontrados nos bancos de dados herdados.

Suponha que você tenha pessoas da tabela em que os nomes das pessoas são armazenados em um único campo PersonName como Nome + '' + Sobrenome. Você precisa selecionar todas as pessoas de uma lista de nomes, armazenada no campo NameToSelect na tabela NamesToSelect , além de alguns critérios adicionais (como filtrados por sexo, data de nascimento, etc.)

Você pode fazer o seguinte

-- @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
bzamfir
fonte
2

Talvez eu tenha uma solução para isso, embora funcione apenas no SQL Server 2008 até onde sei. Descobri que você pode usar o construtor de linhas descrito em https://stackoverflow.com/a/7285095/894974 para ingressar em uma tabela 'fictícia' usando uma cláusula like. Parece mais complexo do que é, veja:

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

Isso resultará em todos os usuários com um endereço de email como os fornecidos na lista. Espero que seja útil para qualquer pessoa. O problema estava me incomodando há um tempo.

Sander
fonte
11
Isso é interessante. No entanto, lembre-se de que isso só deve ser usado em uma tabela smal, pois a instrução like não pode usar índices. É por isso que a pesquisa de texto completo, embora seja mais difícil de configurar inicialmente, é a melhor opção se você tiver muitos dados.
HLGEM
2

A partir de 2016, o SQL Server inclui uma STRING_SPLIT função . Estou usando o SQL Server v17.4 e consegui que isso funcionasse para mim:

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

SELECT * from Project p
JOIN STRING_SPLIT(@dashboard, ',') AS sp ON p.ProjectNumber LIKE sp.value
Marca
fonte
1

Isso funciona para valores separados por vírgula

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

Avalia para:

 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%')

Se você deseja usar índices, deve omitir o primeiro '%'caractere.

David F Mayer
fonte
1

No Oracle RBDMS, você pode obter esse comportamento usando a função REGEXP_LIKE .

O código a seguir testará se a sequência três está presente na expressão de lista um | dois | três | quatro | cinco (em que o símbolo " | " do tubo significa operação lógica OU).

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

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

1 row selected.

A expressão precedente é equivalente a:

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

Então, terá sucesso.

Por outro lado, o teste a seguir falhará.

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

no rows selected

Existem várias funções relacionadas a expressões regulares (REGEXP_ *) disponíveis no Oracle desde a versão 10g. Se você é um desenvolvedor Oracle e está interessado neste tópico, este deve ser um bom começo para Usar expressões regulares com o banco de dados Oracle .

abrittaf
fonte
1

Pode ser que você pense que a combinação assim:

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

Se você definiu o índice de texto completo para sua tabela de destino, poderá usar esta alternativa:

SELECT  * 
FROM    table t
WHERE CONTAINS(t.column, '"bla*" OR "foo*" OR "batz*"')
Humayoun_Kabir
fonte
Obrigado. Esta deve ser a resposta aceita IMO. Nem todo mundo tem um índice de texto completo definido (o que isso significa). Suas primeiras sugestões funcionam como um encanto. Você pode até colocar os curingas nos valores da tabela temporária em vez de concatenar no LIKE.
O tolo
0

Nenhuma resposta como esta:

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

No oracle não há problema.

Hong Van Vit
fonte
0

No Teradata você pode usar LIKE ANY ('%ABC%','%PQR%','%XYZ%'). Abaixo está um exemplo que produziu os mesmos resultados para mim

--===========
--  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%')
Piyush Verma
fonte
0

Sei que é muito tarde, mas tive uma situação semelhante. Eu precisava de um operador "Like In" para um conjunto de procedimentos armazenados que tenho, que aceita muitos parâmetros e os utiliza para agregar dados de vários sistemas RDBMS, portanto, nenhum truque específico do RDBMS funcionaria, no entanto, o procedimento armazenado e quaisquer funções será executado no MS SQL Server, para que possamos usar o T-SQL para a funcionalidade de gerar as instruções SQL completas para cada RDBMS, mas a saída precisa ser bastante independente do RDBMS.

É isso que eu criei no momento para transformar uma string delimitada (como um parâmetro que entra em um procedimento armazenado) em um bloco de SQL. Eu chamo de "Líquen" para "LIKE IN". Pegue?

Lichen.sql

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =======================================================================
-- Lichen - Scalar Valued Function
-- Returns nvarchar(512) of "LIKE IN" results.  See further documentation.
-- CREATOR: Norman David Cooke
-- CREATED: 2020-02-05
-- UPDATED:
-- =======================================================================
CREATE OR ALTER FUNCTION Lichen 
(
    -- Add the parameters for the function here
    @leadingAnd bit = 1,
    @delimiter nchar(1) = ';',
    @colIdentifier nvarchar(64),
    @argString nvarchar(256)
)
RETURNS nvarchar(512)
AS
BEGIN
    -- Declare the return variable here
    DECLARE @result nvarchar(512)

    -- set delimiter to detect (add more here to detect a delimiter if one isn't provided)
    DECLARE @delimit nchar(1) = ';'
    IF NOT @delimiter = @delimit 
        SET @delimit = @delimiter


    -- check to see if we have any delimiters in the input pattern
    IF CHARINDEX(@delimit, @argString) > 1  -- check for the like in delimiter
    BEGIN  -- begin 'like in' branch having found a delimiter
        -- set up a table variable and string_split the provided pattern into it.
        DECLARE @lichenTable TABLE ([id] [int] IDENTITY(1,1) NOT NULL, line NVARCHAR(32))
        INSERT INTO @lichenTable SELECT * FROM STRING_SPLIT(@argString, ';')

        -- setup loop iterators and determine how many rows were inserted into lichen table
        DECLARE @loopCount int = 1
        DECLARE @lineCount int 
        SELECT @lineCount = COUNT(*) from @lichenTable

        -- select the temp table (to see whats inside for debug)
        --select * from @lichenTable

        -- BEGIN AND wrapper block for 'LIKE IN' if bit is set
        IF @leadingAnd = 1
            SET @result = ' AND ('
        ELSE
            SET @result = ' ('

        -- loop through temp table to build multiple "LIKE 'x' OR" blocks inside the outer AND wrapper block
        WHILE ((@loopCount IS NOT NULL) AND (@loopCount <= @lineCount))
        BEGIN -- begin loop through @lichenTable
            IF (@loopcount = 1) -- the first loop does not get the OR in front
                SELECT @result = CONCAT(@result, ' ', @colIdentifier, ' LIKE ''', line, '''') FROM @lichenTable WHERE id = @loopCount
            ELSE  -- but all subsequent loops do
                SELECT @result = CONCAT(@result, ' OR ', @colIdentifier, ' LIKE ''', line, '''') FROM @lichenTable WHERE id = @loopCount
            SET @loopcount = @loopCount + 1     -- increment loop
        END -- end loop through @lichenTable

        -- set final parens after lichenTable loop
        SET @result = CONCAT(@result, ' )')
    END  -- end 'like in' branch having found a delimiter
    ELSE -- no delimiter was provided
    BEGIN   -- begin "no delimiter found" branch
        IF @leadingAnd = 1 
            SET @result = CONCAT(' AND ', @colIdentifier, ' LIKE ''' + @argString + '''')
        ELSE
            SET @result = CONCAT(' ', @colIdentifier, ' LIKE ''' + @argString + '''')
    END     -- end "no delimiter found" branch

    -- Return the result of the function
    RETURN @result
END  -- end lichen function

GO

A detecção do delimitador é possivelmente planejada, mas, por enquanto, o padrão é um ponto-e-vírgula, para que você possa colocar defaultlá. Provavelmente existem erros nisso. O @leadingAndparâmetro é apenas um valor de bit para determinar se você deseja colocar um "AND" inicial na frente do bloco para que ele se encaixe perfeitamente com outras adições à cláusula WHERE.

Exemplo de uso (com delimitador em argString)

SELECT [dbo].[Lichen] (
   default        -- @leadingAND, bit, default: 1
  ,default        -- @delimiter, nchar(1), default: ';'
  ,'foo.bar'      -- @colIdentifier, nvarchar(64), this is the column identifier
  ,'01%;02%;%03%' -- @argString, nvarchar(256), this is the input string to parse "LIKE IN" from
)
GO

Retornará um nvarchar (512) contendo:

 AND ( foo.bar LIKE '01%' OR foo.bar LIKE '02%' OR foo.bar LIKE '%03%' ) 

Ele também ignorará o bloco se a entrada não contiver um delimitador:

Exemplo de uso (sem delimitador em argString)

SELECT [dbo].[Lichen] (
   default        -- @leadingAND, bit, default: 1
  ,default        -- @delimiter, nchar(1), default: ';'
  ,'foo.bar'      -- @colIdentifier, nvarchar(64), this is the column identifier
  ,'01%'          -- @argString, nvarchar(256), this is the input string to parse "LIKE IN" from
)
GO

Retornará um nvarchar (512) contendo:

 AND foo.bar LIKE '01%'

Vou continuar trabalhando nisso, por isso, se negligenciei algo (claramente óbvio ou não), fique à vontade para comentar ou entrar em contato.

NDC
fonte
-3

faça isso

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

ou

WHERE something + '%' in (select col from table where ....)
Nikolay Hristov
fonte
11
Como isso vai funcionar? O LHS é uma cadeia de caracteres com um%, e que é, por conseguinte, não% de um carácter universal
Darius X.