Сочетание 'LIKE' и 'IN' с использованием t-sql - PullRequest
35 голосов
/ 24 мая 2011

Как я могу сделать такой выбор:

SELECT * 
FROM Street 
WHERE StreetName LIKE IN ('% Main Street', 'foo %')

Пожалуйста, не говорите мне, что я могу использовать OR, потому что это на самом деле происходит из запроса.

Ответы [ 6 ]

36 голосов
/ 24 мая 2011

Нет объединенного синтаксиса LIKE и IN, но вы можете использовать от LIKE до JOIN для вашего запроса, как показано ниже.

;WITH Query(Result) As
(
SELECT '% Main Street' UNION ALL
SELECT 'foo %'
)
SELECT DISTINCT s.* 
FROM Street s
JOIN Query q ON StreetName LIKE q.Result

Или использовать ваш пример в комментариях

SELECT DISTINCT s.* 
FROM Street s
JOIN CarStreets cs ON s.StreetName LIKE cs.name + '%'
WHERE cs.Streets = 'offroad'
4 голосов
/ 24 мая 2011

У вас нет большого выбора здесь.

SELECT * FROM Street Where StreetName LIKE '% Main Street' OR StreetName LIKE 'foo %'

Если это часть существующего, более сложного запроса (это впечатление, которое я получаю), вы могли бы создать функцию табличного значения, которая выполняет проверку за вас.

SELECT * FROM Street Where StreetName IN (dbo.FindStreetNameFunction('% Main Street|foo %'))

Я бы рекомендовал использовать самое простое решение (первое). Если это вложено в более крупный и сложный запрос, опубликуйте его, и мы посмотрим.

1 голос
/ 15 июня 2015

Вы можете прибегнуть к Dynamic SQL и обернуть все в хранимую процедуру.

Если вы получите параметр LIKE IN в строке как токены с определенным разделителем, например

'% Main Street,foo %,Another%Street'

сначала вам нужно создать функцию, которая получает список LIKE "токенов" и возвращает их таблицу.

CREATE FUNCTION [dbo].[SplitList]
(
  @list nvarchar(MAX),
  @delim nvarchar(5)
)  
RETURNS @splitTable table 
(       
  value nvarchar(50)
) 
AS BEGIN
  While (Charindex(@delim, @list)>0) Begin 
    Insert Into @splitTable (value)
      Select ltrim(rtrim(Substring(@list, 1, Charindex(@delim, @list)-1))) 
    Set @list = Substring(@list, Charindex(@delim, @list)+len(@delim), len(@list))
  End     
  Insert Into @splitTable (value) Select ltrim(rtrim(@list))
  Return
END 

Тогда в SP у вас есть следующий код

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

-- prepare the where sub-clause to cover LIKE IN (...)
-- it will actually generate where sub clause StreetName Like option1 or StreetName Like option2 or ...   
set @subWhere = STUFF(
  (
    --(**)
    SELECT ' OR StreetName like ''' + value + '''' FROM SplitList('% Main Street,foo %,Another%Street', ',') 
      FOR XML PATH('')
  ), 1, 4, '')

-- create the dynamic SQL
set @sql ='select * from [Street]
  where 
    (' + @subWhere + ')
    -- and any additional query params here, if needed, like
    AND StreetMinHouseNumber = @minHouseNumber
    AND StreetNumberOfHouses between (@minNumberOfHouses and @maxNumberOfHouses)'

set @params = ' @minHouseNumber nvarchar(5),
  @minNumberOfHouses int,
  @minNumberOfHouses int'     

EXECUTE sp_executesql @sql, @params,    
  @minHouseNumber,
  @minNumberOfHouses,
  @minNumberOfHouses     

Конечно, если у вас есть параметры LIKE IN в другой таблице или вы собираете их с помощью запроса, вы можете заменить их в строке (**)

0 голосов
/ 12 ноября 2018

У меня была похожая головоломка, но из-за необходимости совпадать только с началом строки я изменил свое «как» на SUBSTRING как таковое:

SELECT *  
FROM codes  
WHERE SUBSTRING(code, 1, 12) IN ('012316963429', '012315667849')  
0 голосов
/ 14 августа 2018

Это мой способ:

Сначала создайте табличную функцию:

create function [splitDelimeter](@str nvarchar(max), @delimeter nvarchar(10)='*')
returns @r table(val nvarchar(max))
as
begin

    declare @x nvarchar(max)=@str
    set @x='<m>'+replace(@x, @delimeter, '</m><m>')+'</m>'

    declare @xx xml=cast(@x as xml)

    insert @r(val)
    SELECT Tbl.Col.value('.', 'nvarchar(max)') id
    FROM @xx.nodes('/m') Tbl(Col)

    return 
end

Затем разделите текст поиска с помощью своего разделителя предпочтений.После этого вы можете сделать выбор с помощью левого соединения, как показано ниже:

  declare @s nvarchar(max)='% Main Street*foo %'

  select a.* from street a
     left join gen.splitDelimeter(@s, '*') b
        on a.streetname like b.val
  where val is not null
0 голосов
/ 12 июля 2016

Полагаю, я могу уточнить, что он ищет, но я не знаю ответа. Я буду использовать мою ситуацию, чтобы продемонстрировать. У меня есть таблица со столбцом под названием «Запрос», который содержит запросы SQL. Эти запросы иногда содержат имена таблиц из одной из моих баз данных. Мне нужно найти все строки запроса, которые содержат имена таблиц из конкретной базы данных. Итак, я могу использовать следующий код для получения имен таблиц:

SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES

Я пытаюсь использовать предложение WHERE IN для определения строк запроса, которые содержат имена таблиц, которые меня интересуют:

SELECT *
  FROM [DatasourceQuery]
 WHERE Query IN LIKE
(
    SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
)

Я полагаю, что ОП пытается сделать что-то подобное.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...