Сочетание LIKE с IN в SQL - PullRequest
4 голосов
/ 19 июня 2009

Вместо выполнения:

ВЫБЕРИТЕ
ОТ Б
ГДЕ КАК '%'
ИЛИ КАК 'b%'
ИЛИ КАК 'c%'


Есть ли способ выполнить что-то вроде этого псевдокода?

ВЫБЕРИТЕ
ОТ Б
ГДЕ IN IN ('a%', 'b%', 'c%')

Ответы [ 6 ]

9 голосов
/ 19 июня 2009

Может быть слишком конкретным для вашего примера, но вы можете сделать, как '[a-c]%' Кроме этого, я не знаю ни одного похожего синтаксиса IN

5 голосов
/ 20 июня 2009

Вы можете записать значения критериев во временную таблицу (без подстановочного знака). Затем сделайте соединение как:

SELECT b.a FROM b INNER JOIN #likevals on b.a LIKE #likevals.value + '%'

ГДЕ #likevals выглядит:

value
------
a
b
c
3 голосов
/ 19 июня 2009

Вы можете использовать

SELECT a
FROM b
WHERE a >= 'A'
AND a < 'D'

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

Бьюсь об заклад, другой ответ даст вам сканирование индекса или таблицы.

2 голосов
/ 05 апреля 2012

Просто заметил это. Есть много способов ее решения, но вот один гибкий метод, который вы можете использовать с решениями для составления отчетов. Мне просто довелось решить одну и ту же проблему в прошлом, и я никогда не передавал проблему; о). Заранее извиняюсь, если это не разбирается - забил и возился с памятью, но вы должны понять -

CREATE FUNCTION fn_PatList (@PatList VARCHAR(200))
RETURNS @SearchList TABLE (Pattern VARCHAR(100))
AS 
BEGIN
 WHILE @PatList LIKE '%,%'
 BEGIN
  SELECT @PatList = LTRIM(RTRIM(@PatList))
  INSERT INTO @SearchList
   SELECT RTRIM(LEFT(@PatList,PATINDEX('%,%',@PatList)-1))
  SELECT @PatList = SUBSTRING(@PatListmPATINDEX('%,%',@PatList)+1, 8000)
 END
 INSERT INTO @SearchList 
  SELECT LTRIM(RTRIM(@PatList))
 RETURN
END

Это общая суть - извинения за любые ошибки до сих пор. Биты, чтобы сделать в ближайшее время.

Теперь ..

SELECT Names.Person
FROM Names
INNER JOIN Fn_PatList ('Fred%,John%') PatList
ON Names.Person LIKE PatList.Pattern

Возможно, вы захотите разрешить пробелы, то есть пробелы между запятыми и другим мусором. Короче говоря, теперь вы можете использовать свою функцию для обслуживания списков шаблонов. Надеюсь, это удовлетворяет вашим требованиям - с ними довольно легко работать. Возможно, вам захочется рассмотреть вопрос и об индексации, но вы можете взять ее оттуда.

0 голосов
/ 25 ноября 2011

У меня была такая же проблема, мне пришлось написать сценарий для нее. (Если это все еще у вас на уме)

вот что я в итоге использовал:

 DECLARE @User INT, @MaskCount INT
     SET @User = 1
     Select @MaskCount = COUNT(*) from BI.dbo.ALL_Access_Masks

     WHILE (@User <= @MaskCount)
        Begin

        DECLARE @ProntoUserID Nvarchar (12)
        Set @ProntoUserID = (select Distinct [USER_ID] from BI.dbo.ALL_Access_Masks where [ID] = @User)

        DECLARE @DB Nvarchar (3)
        Set @DB = (select Distinct DB_Code from BI.dbo.ALL_Access_Masks where [ID] = @User)


        DECLARE @TopFlag INT
        SET @TopFlag = 1

            Drop Table #UserMasks 
            Drop Table #UserMasks1 

            Create Table #UserMasks
            ([RN] [Int] NOT NULL,
            [DB] [Nvarchar] (3) NOT NULL,
            [Mask] [Nvarchar](10) NOT NULL)

            Create Table #UserMasks1
            ([DB] [Nvarchar] (3) NOT NULL,
            [Mask] [Nvarchar](10) NOT NULL)

            Insert Into #UserMasks1 

                select @DB ,PD_Mk_1  from BI.dbo.ALL_Access_Masks where [ID] = @User and PD_Mk_1 is not NULL
                Union All select @DB ,PD_Mk_2  from BI.dbo.ALL_Access_Masks where [ID] = @User and PD_Mk_2  is not null and DB_Code = @DB
                Union All select @DB ,PD_Mk_3  from BI.dbo.ALL_Access_Masks where [ID] = @User and PD_Mk_3  is not null and DB_Code = @DB
                Union All select @DB ,PD_Mk_4  from BI.dbo.ALL_Access_Masks where [ID] = @User and PD_Mk_4  is not null and DB_Code = @DB
                Union All select @DB ,PD_Mk_5  from BI.dbo.ALL_Access_Masks where [ID] = @User and PD_Mk_5  is not null and DB_Code = @DB
                Union All select @DB ,PD_Mk_6  from BI.dbo.ALL_Access_Masks where [ID] = @User and PD_Mk_6  is not null and DB_Code = @DB
                Union All select @DB ,PD_Mk_7  from BI.dbo.ALL_Access_Masks where [ID] = @User and PD_Mk_7  is not null and DB_Code = @DB
                Union All select @DB ,PD_Mk_8  from BI.dbo.ALL_Access_Masks where [ID] = @User and PD_Mk_8  is not null and DB_Code = @DB
                Union All select @DB ,PD_Mk_9  from BI.dbo.ALL_Access_Masks where [ID] = @User and PD_Mk_9  is not null and DB_Code = @DB
                Union All select @DB ,PD_Mk_10 from BI.dbo.ALL_Access_Masks where [ID] = @User and PD_Mk_10 is not null and DB_Code = @DB


            Insert Into #UserMasks

                Select ROW_NUMBER() OVER ( PARTITION BY @DB ORDER BY Mask DESC) AS RN,DB,Mask from #UserMasks1
                where DB = @DB


        WHILE (@TopFlag <=(select COUNT(*) from #UserMasks))

                        BEGIN

                            Insert Into BI.dbo.Masked_Users
                            select @DB,@ProntoUserID,'PD' as 'Mask_Type',Code
                            from BI.dbo.Mask_Lookup M
                            where code like (select Mask + '%' from #UserMasks Where RN = @TopFlag)
                            and [Database] = @DB and M.Mask = 'PD'

        SET @TopFlag = @TopFlag + 1

                    End

        SET @User = @User + 1

End

GO
0 голосов
/ 19 июня 2009

Нет. Оператор IN ожидает фактические значения. Самое близкое, что вы можете получить, это что-то вроде:

Select a
from b 
where a in (
    select a 
    from b
    WHERE a LIKE 'a%'
    OR a LIKE 'b%'
    OR a LIKE 'c%')

За исключением того, что это просто дублирует ваши усилия в данном конкретном случае, поэтому я не буду использовать приведенный выше код. По сути, вам нужно передать фактические значения в ваш оператор IN. Вывод здесь заключается в том, что вы можете использовать оператор select внутри оператора IN для получения ваших значений.

Кроме того, я здесь исходил из того, что вы не пытаетесь выбрать буквенные значения «a», «b», «c» и т. Д. И что эти значения представляют собой некоторую другую строку, которая вас не волнует чтобы показать нам.

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