Есть ли в SQL комбинация «LIKE» и «IN»?

341

В SQL я (к сожалению) часто вынужден использовать « LIKE» условия из-за баз данных, которые нарушают почти все правила нормализации. Я не могу изменить это прямо сейчас. Но это не имеет отношения к вопросу.

Кроме того, я часто использую такие условия, как WHERE something in (1,1,2,3,5,8,13,21)для лучшей читаемости и гибкости моих операторов SQL.

Есть ли возможный способ объединить эти две вещи без написания сложных подвыборов?

Я хочу что-то так просто, как WHERE something LIKE ('bla%', '%foo%', 'batz%')вместо этого:

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

Я работаю здесь с SQl Server и Oracle, но мне интересно, возможно ли это вообще в любой СУБД.

selfawaresoup
источник
1
Вы должны делать и любить или: И (что-то НРАВИТСЯ '% thing%' или что-то НРАВИТСЯ '% thing%' или что-то НРАВИТСЯ '% thing%')
Cosmic Hawk
Хотелось бы, чтобы у нас был Teradata like any/ like all: stackoverflow.com/questions/40475982/sql-like-any-vs-like-all . (Для сведения, это было запрошено на форуме Oracle Community Ideas community.oracle.com/ideas/11592 )
Уильям Робертсон,
Аналогичный stackoverflow.com/q/1076097/125981
Марк Шультхайс

Ответы:

196

В SQL нет комбинации LIKE & IN, а тем более в TSQL (SQL Server) или PLSQL (Oracle). Частично это объясняется тем, что полнотекстовый поиск (FTS) является рекомендуемой альтернативой.

Реализации FTS как Oracle, так и SQL Server поддерживают ключевое слово CONTAINS, но синтаксис все же немного отличается:

Oracle:

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

SQL Server:

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

Столбец, который вы запрашиваете, должен быть полнотекстовым индексированным.

Ссылка:

OMG пони
источник
11
Привет, с Oracle, вам нужно построить незашифрованные индексы для столбцов, к которым вы хотите применить оператор «CONTAINS». В зависимости от объема ваших данных это может быть довольно долго.
Пьер-Жиль Леваллуа
18
С SQL Server (по крайней мере, версия 2008) комментарий @Pilooz также применим, вам нужно создавать полнотекстовые индексы.
Марсель
Максимальная длина 4000.
ʙᴀᴋᴇʀ ʙᴀᴋᴇʀ
59

Если вы хотите, чтобы ваше заявление было легко читаемым, вы можете использовать REGEXP_LIKE (доступно начиная с версии Oracle 10).

Пример таблицы:

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.

Оригинальный синтаксис:

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.

И простой запрос с REGEXP_LIKE

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

SOMETH
------
blabla
ofooof
batzzz

3 rows selected.

НО ...

Я не рекомендовал бы это сам из-за не очень хорошей работы. Я бы придерживался нескольких предикатов LIKE. Так что примеры были просто для удовольствия.

Роб ван Вейк
источник
4
+1 хорошая иллюстрация использования REGEXP в 10г. Мне любопытно, если бы производительность действительно была намного хуже. Оба требуют полного сканирования таблицы и / или индекса, не так ли?
DCookie
12
Правда. Но регулярные выражения сжигают процессор как сумасшедший, а не ввод / вывод. Если оно хуже и насколько оно хуже, зависит от того, насколько велик ваш список выражений и индексирован ли столбец или нет. Это всего лишь предупреждение, так что оригинальный постер не удивляется, когда начинает его реализовывать.
Роб ван Вейк
49

ты застрял с

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

если вы не заполнили временную таблицу (включите подстановочные знаки с данными) и присоединились следующим образом:

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

попробуйте это (используя синтаксис 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

ВЫВОД:

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

(2 row(s) affected)

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

(2 row(s) affected)
KM.
источник
Хорошо, это сработало бы, но это не входит в мое намерение сделать оператор SQL более читабельным :)
selfawaresoup
10
в SQL вы идете для использования индекса и производительности. Используйте отступы и имена только для удобства чтения SQL, когда вы вносите другие изменения для удобства чтения, вы рискуете изменить план выполнения (что влияет на использование индекса и производительность). Если вы не будете осторожны, вы можете легко изменить мгновенно выполняющийся запрос на очень медленный, сделав тривиальные изменения.
КМ.
Первое утверждение этого ответа является ключевым - (большинство?) Основанные на SQL системы и языки не поддерживают то, что вы хотите, не без реализации обходных путей. (В SQL-сервере поможет ли полнотекстовая индексация?)
Филипп Келли
@Philip Kelley, может ли полнотекстовая индексация SQL Server делать LIKE 'bla%' , что в примере кода OP? или может только в LIKE '%bla%'поисках?
КМ.
Честно говоря, я не знаю, я никогда не использовал индексирование FT. Я добавил это как пример возможного обходного пути, которое уже включено в продукт. Для того, что он делает (A или B или C), я подозреваю, что он этого не делает, я вполне уверен, что потребуется много усилий, чтобы определить это, и знаю, что это выходит за рамки его первоначального вопроса (делает SQL делает это изначально).
Филипп Келли
20

В PostgreSQL есть форма ANYили ALL:

WHERE col LIKE ANY( subselect )

или

WHERE col LIKE ALL( subselect )

где подвыбор возвращает ровно один столбец данных.

Benoit
источник
1
Существуют LIKE ANYи LIKE ALLобщие для всех диалектов SQL, т.е. часть основного языка, или специфичной для диалекте?
Асад Эбрахим
1
@ AssadEbrahim, нет, они конкретные. Oracle имеет = ANYили <> ALLработает только в SQL, а не в PLSQL, например.
Бенуа
Я думаю, что это стандартный синтаксис (но не многие СУБД реализовали его)
ypercubeᵀᴹ
Для Postgres см stackoverflow.com/questions/2245536/...
rogerdpack
13

Другое решение, должно работать на любой 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)
МИК
источник
1
Но это хуже, чем набор операторов ИЛИ
Fandango68
1
@ Fandango68, но объединение выбирает может быть заменен другим источником шаблонов , как таблицы, вид и т.д.
МИК
10

Я бы предложил использовать пользовательскую функцию TableValue, если вы хотите инкапсулировать методы Inner Join или Temp Table, показанные выше. Это позволило бы читать немного яснее.

После использования функции разделения, определенной по адресу: http://www.logiclabz.com/sql-server/split-function-in-sql-server-to-break-comma-separated-strings-into-table.aspx

мы можем написать следующее на основе созданной мною таблицы «Рыба» (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.

Выходы

1 бас
2 щука
7 рыболов
8 Судак
Знаменитый ботаник
источник
1
Строка будет продублирована, если она соответствует многим условиям одновременно.
Мик
7

Одним из подходов было бы сохранить условия во временной таблице (или табличной переменной в SQL Server) и присоединиться к ней следующим образом:

SELECT t.SomeField
FROM YourTable t
   JOIN #TempTableWithConditions c ON t.something LIKE c.ConditionValue
AdaTheDev
источник
Строка будет продублирована, если она соответствует многим условиям одновременно.
Мик
7

Вместо этого используйте внутреннее соединение:

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
Аляска
источник
1
Ну, это именно то, чего я хотел бы избежать. Хотя это работает.
selfawaresoup
Зачем избегать этого решения? Он работает так же быстро, как принятое решение, и столь же универсален.
Фил Фактор
3
@PhilFactor Это решение может создавать повторяющиеся строки.
Якуб Кания
5

Я работаю здесь с SQl Server и Oracle, но мне интересно, возможно ли это вообще в любой СУБД.

Teradata поддерживает синтаксис LIKE ALL / ANY :

ВСЕ каждая строка в списке.
ЛЮБАЯ любая строка в списке.

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

РЕДАКТИРОВАТЬ:

jOOQ версии 3.12.0 поддерживает этот синтаксис:

Добавить синтетические [NOT] LIKE ANY и [NOT] LIKE ALL операторы

Часто пользователи SQL хотели бы иметь возможность комбинировать предикаты LIKE и IN, например:

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

Обходной путь - вручную расширить предикат до эквивалентного

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

JOOQ может поддерживать такой синтетический предикат из коробки.


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


Снежинка также поддерживает LIKE ANY / LIKE ALL соответствия:

КАК ЛЮБОЙ / ВСЕ

Позволяет сопоставлять строки с учетом регистра на основе сравнения с одним или несколькими шаблонами.

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

Пример:

SELECT * 
FROM like_example 
WHERE subject LIKE ANY ('%Jo%oe%','T%e')
-- WHERE subject LIKE ALL ('%Jo%oe%','J%e')
Лукаш Шозда
источник
4

ты можешь даже попробовать это

функция

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+'%';
Симаржит Сингх Панхлия
источник
4

У меня есть простое решение, которое работает, по крайней мере, в postgresql , с использованием like anyсписка регулярных выражений. Вот пример, глядя на выявление некоторых антибиотиков в списке:

select *
from database.table
where lower(drug_name) like any ('{%cillin%,%cyclin%,%xacin%,%mycine%,%cephal%}')
mkomo
источник
3

Мне тоже было интересно что-то подобное. Я только что проверил, используя комбинацию SUBSTRINGи, INи это эффективное решение для такого рода проблемы. Попробуйте следующий запрос:

Select * from TB_YOUR T1 Where SUBSTRING(T1.Something, 1,3) IN ('bla', 'foo', 'batz')
ssah
источник
1
одна проблема с этим подходом - вы теряете возможность использовать индекс для t1.something, если он существует ..
ShoeLace
1
это никогда не найдет «Batz»
МИК
3

В Oracle вы можете использовать коллекцию следующим образом:

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

Здесь я использовал предопределенный тип коллекции ku$_vcnt, но вы можете объявить свой собственный так:

CREATE TYPE my_collection AS TABLE OF VARCHAR2(4000);
МИК
источник
2

Для Sql Server вы можете прибегнуть к динамическому SQL.

В большинстве случаев в таких ситуациях у вас есть параметр предложения IN, основанный на некоторых данных из базы данных.

Приведенный ниже пример немного «принудительный», но он может соответствовать различным реальным случаям, найденным в устаревших базах данных.

Предположим, у вас есть таблица Persons, в которой имена людей хранятся в одном поле PersonName как FirstName + '' + LastName. Вам необходимо выбрать всех людей из списка имен, хранящегося в поле NameToSelect в таблице NamesToSelect , а также некоторые дополнительные критерии (например, отфильтрованные по полу, дате рождения и т. Д.)

Вы можете сделать это следующим образом

-- @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
источник
2

У меня может быть решение для этого, хотя оно будет работать только в SQL Server 2008, насколько я знаю. Я обнаружил, что вы можете использовать конструктор строк, описанный в https://stackoverflow.com/a/7285095/894974, чтобы присоединиться к «вымышленной» таблице с помощью предложения like. Это звучит сложнее, чем это, смотрите:

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

Это приведет к тому, что все пользователи будут иметь адреса электронной почты, подобные тем, которые указаны в списке. Надеюсь, это кому-нибудь пригодится. Проблема беспокоила меня некоторое время.

шлифовальный
источник
1
Это интересно. Однако имейте в виду, что это следует использовать только для небольшой таблицы, поскольку оператор like не может использовать индексы. Вот почему полнотекстовый поиск, хотя его сложнее изначально настроить, является лучшим выбором, если у вас много данных.
HLGEM
2

Начиная с 2016 года, SQL Server включает STRING_SPLIT функцию . Я использую SQL Server v17.4, и у меня это работает:

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

SELECT * from Project p
JOIN STRING_SPLIT(@dashboard, ',') AS sp ON p.ProjectNumber LIKE sp.value
отметка
источник
1

Это работает для значений, разделенных запятыми

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

Оценивает:

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

Если вы хотите, чтобы он использовал индексы, вы должны опустить первый '%'символ.

Дэвид Ф Майер
источник
1

В Oracle RBDMS вы можете добиться этого, используя функцию REGEXP_LIKE .

Следующий код проверит, присутствует ли строка три в выражении списка one | два | три | четыре | пять (в котором символ " | " канала означает логическую операцию ИЛИ).

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

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

1 row selected.

Предыдущее выражение эквивалентно:

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

Так и получится.

С другой стороны, следующий тест не пройден.

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

no rows selected

Существует несколько функций, связанных с регулярными выражениями (REGEXP_ *), доступных в Oracle начиная с версии 10g. Если вы разработчик Oracle и заинтересована эта тема , это должно быть хорошим началом Использования регулярных выражений с Oracle Database .

abrittaf
источник
1

Может быть, вы думаете, комбинация, как это:

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

Если вы определили полнотекстовый индекс для вашей целевой таблицы, вы можете использовать эту альтернативу:

SELECT  * 
FROM    table t
WHERE CONTAINS(t.column, '"bla*" OR "foo*" OR "batz*"')
Humayoun_Kabir
источник
Спасибо. Это должен быть принятый ответ ИМО. Не у всех есть определенный полнотекстовый индекс (что бы это ни значило). Ваши первые предложения работают как шарм. Вы даже можете поместить символы подстановки в сами значения временных таблиц вместо конкатенации в LIKE.
Дурак
0

Нет ответа, как это:

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

У оракула нет проблем.

Хонг Ван Вит
источник
0

В Teradata вы можете использовать LIKE ANY ('%ABC%','%PQR%','%XYZ%'). Ниже приведен пример, который дал те же результаты для меня

--===========
--  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%')
Пиюш Верма
источник
0

Я знаю, что очень поздно, но у меня была похожая ситуация. Мне понадобился оператор «Like In» для набора хранимых процедур, который принимает много параметров, а затем использует эти параметры для агрегирования данных из нескольких систем RDBMS, поэтому никакие специфичные для RDBMS приемы не будут работать, однако хранимая процедура и любые функции будет работать на MS SQL Server, поэтому мы можем использовать T-SQL для функциональности генерации полных операторов SQL для каждой СУБД, но выходные данные должны быть достаточно независимыми от СУБД.

Это то, что я на данный момент придумал, чтобы превратить разделенную строку (например, параметр, входящий в хранимую процедуру) в блок SQL. Я называю это «лишайником» для «LIKE IN». Возьми?

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

Обнаружение разделителя возможно запланировано, но сейчас по умолчанию используется точка с запятой, так что вы можете просто вставить его defaultтуда. В этом, вероятно, есть ошибки. @leadingAndПараметр только немного значение , чтобы определить , если вы хотите , ведущий «И» положить в передней части блока , так что прекрасно вписывается в другие предложения WHERE добавлений.

Пример использования (с разделителем в 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

Вернет nvarchar (512), содержащий:

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

Он также пропустит блок, если на входе нет разделителя:

Пример использования (без разделителя в 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

Вернет nvarchar (512), содержащий:

 AND foo.bar LIKE '01%'

Я собираюсь продолжить работу над этим, поэтому, если я что-то упустил (явно очевидное или иное), пожалуйста, не стесняйтесь комментировать или обратиться.

NDC
источник
-3

сделай это

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

или

WHERE something + '%' in (select col from table where ....)
Николай Христов
источник
1
Как это будет работать? LHS - это строка с%, поэтому этот% не является подстановочным знаком
Дарий X.