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과 함께 일하고 있지만 RDBMS에서 이것이 가능한지 관심이 있습니다.


1
AND ( '% thing %'와 같은 것 또는 '% thing %'와 같은 것 또는 '% thing %'와 같은 것)
Cosmic Hawk

Teradata의 like any/ like all: stackoverflow.com/questions/40475982/sql-like-any-vs-like-all 이 있었으면 좋겠습니다 . (기록을 위해, 이것은 Oracle Community Ideas forum community.oracle.com/ideas/11592 에서 요청되었습니다 )
William Robertson

답변:


196

SQL에는 LIKE & IN의 조합이 없으며 TSQL (SQL Server) 또는 PLSQL (Oracle)에는 훨씬 적습니다. 그 이유 중 일부는 전체 텍스트 검색 (FTS)이 권장되는 대안이기 때문입니다.

Oracle 및 SQL Server FTS 구현 모두 CONTAINS 키워드를 지원하지만 구문은 여전히 ​​약간 다릅니다.

신탁:

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

SQL 서버 :

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

쿼리하는 열은 전체 텍스트 인덱싱되어야합니다.

참고:


11
안녕하세요, Oracle에서는 "CONTAINS"연산자를 적용하려는 열에 일반 텍스트 인덱스를 작성해야합니다. 데이터 볼륨에 따라 상당히 길 수 있습니다.
Pierre-Gilles Levallois

18
SQL Server (최소 2008 버전)에서는 @Pilooz에 대한 설명도 적용되므로 전체 텍스트 인덱스를 작성해야합니다.
Marcel

최대 길이는 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
10g의 REGEXP 사용량에 대한 멋진 그림 1 개. 그러나 성능이 실제로 훨씬 나빠질 지 궁금합니다. 둘 다 전체 테이블 및 / 또는 인덱스 스캔이 필요합니까?
DCookie

12
진실. 그러나 정규 표현식은 CPU가 I / O가 아닌 미친 것처럼 구워집니다. 더 나쁘고 더 나쁘면 표현식 목록의 크기와 열의 색인 생성 여부에 따라 다릅니다. 원래 포스터가 포스터를 구현할 때 놀라지 않도록 경고 일뿐입니다.
Rob van Wijk

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)

좋아, 이것은 작동하지만 SQL 문을 더 쉽게 읽을 수 있도록 의도 한 방향으로 가고 있지는 않습니다. :)
selfawaresoup

10
SQL에서는 인덱스 사용법과 성능을 추구합니다. 가독성을 높이기 위해 들여 쓰기 및 명명 만 사용하십시오. 가독성을 위해 다른 수정을 할 경우에만 실행 계획을 변경해야 할 위험이 있습니다 (인덱스 사용 및 성능에 영향을 미침). 주의하지 않으면 간단한 변경을 통해 즉시 실행중인 쿼리를 매우 느린 쿼리로 쉽게 변경할 수 있습니다.
KM.

이 답변의 첫 번째 진술은 핵심입니다. (대부분?) SQL 기반 시스템 및 언어는 해결 방법을 구현하지 않고 원하는 것을 지원하지 않습니다. (SQL 서버에서 전체 텍스트 인덱싱이 도움이 되었습니까?)
Philip Kelley 2016 년

@Philip Kelley, LIKE 'bla%' OP의 예제 코드에서 SQL Server의 전체 텍스트 인덱싱을 수행 할 수 있습니까? 아니면 LIKE '%bla%'검색 만 할 수 있습니까?
KM.

나는 솔직히 모르겠다. 나는 결코 FT 인덱싱을 사용한 적이 없다. 이미 제품에 포함되어있는 가능한 해결 방법의 샘플로 제공했습니다. 그는 (A 또는 B 또는 C)를 무엇을하고 있는지, 나는 의심 , 그것을하지 않습니다는이를 결정하기 위해 많은 노력을하고, 그 밖에 자신의 원래 질문의 범위 (않는다는 것을 알 거라고 꽤 확신 SQL은 기본적으로 수행합니다.
Philip Kelley

20

PostgreSQL에는 다음 ANY과 같은 ALL형식이 있습니다.

WHERE col LIKE ANY( subselect )

또는

WHERE col LIKE ALL( subselect )

여기서 subselect는 정확히 하나의 데이터 열을 리턴합니다.


1
인가 LIKE ANY하고 LIKE ALL, 모든 SQL 언어로 방언의 핵심 언어, 또는 특정의 즉, 일부 공통?
Assad Ebrahim

1
@AssadEbrahim, 구체적이지 않습니다. 오라클이 = ANY<> ALL있지만, 예를 들어하지 PLSQL에서 만 SQL에서 작동합니다.
Benoit

나는 이것이 표준 구문이라고 생각하지만 (많은 DBMS가 그것을 구현하지는 않았다)
ypercubeᵀᴹ

포스트 그레스를 참조 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
그러나 그것은 일련의 OR 진술보다 더 나쁘다
Fandango68

1
@ Fandango68, 그러나 선택 조합은 테이블, 뷰 등과 같은 다른 패턴 소스로 대체 될 수 있습니다.
mik

10

위에 표시된 내부 조인 또는 임시 테이블 기술을 캡슐화하려면 TableValue 사용자 함수를 사용하는 것이 좋습니다. 이를 통해 좀 더 명확하게 읽을 수 있습니다.

http://www.logiclabz.com/sql-server/split-function-in-sql-server-to-break-comma-separated-strings-into-table.aspx에 정의 된 split 함수를 사용한 후

"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.

출력

베이스 1 개
파이크
7 낚시꾼
8 월 아이

1
한 번에 여러 조건과 일치하면 행이 복제됩니다.
mik

7

한 가지 방법은 임시 테이블 (또는 SQL Server의 테이블 변수)에 조건을 저장하고 다음과 같이 조인하는 것입니다.

SELECT t.SomeField
FROM YourTable t
   JOIN #TempTableWithConditions c ON t.something LIKE c.ConditionValue

한 번에 여러 조건과 일치하면 행이 복제됩니다.
mik

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 2016 년

왜이 솔루션을 피해야합니까? 허용되는 솔루션만큼 빠르게 작동하며 다목적입니다.
Phil Factor

3
@PhilFactor이 솔루션은 중복 행을 만들 수 있습니다.
Jakub Kania

5

SQl Server 및 Oracle과 함께 일하고 있지만 RDBMS에서 이것이 가능한지 관심이 있습니다.

Teradata는 LIKE ALL / ANY 구문을 지원 합니다.

ALL 목록에있는 모든 문자열입니다.
모든 목록에서 임의의 문자열.

┌──────────────────────────────┬────────────────────────────────────┐
      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 <> 바이올린 데모


Snowflake는 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%}')

3

나는 또한 그런 것을 궁금해하고있었습니다. 나는 단지의 조합을 사용하여 테스트 SUBSTRINGIN그것은 이런 종류의 문제에 대한 효과적인 솔루션입니다. 아래 쿼리를 시도하십시오.

Select * from TB_YOUR T1 Where SUBSTRING(T1.Something, 1,3) IN ('bla', 'foo', 'batz')

1
이 접근법의 한 가지 문제는 t1.something에 인덱스를 사용할 수있는 능력을 잃어 버리는 것입니다.
ShoeLace

1
이것은 'batz'를 찾지 못할 것입니다
mik

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 절의 매개 변수가 있습니다.

아래 예제는 "강제"이지만 약간은 레거시 데이터베이스에서 발견되는 다양한 실제 사례와 일치 할 수 있습니다.

PersonName 이 단일 필드 PersonName 에 FirstName + ''+ LastName으로 저장된 Person 테이블이 있다고 가정하십시오 . NamesToSelect 테이블의 NameToSelect 필드에 저장된 이름 목록에서 모든 사람을 선택하고 몇 가지 추가 기준 (성별, 생년월일 필터링 등)을 선택해야합니다.

다음과 같이 할 수 있습니다

-- @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

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를 사용하여이 동작을 수행 할 수 있습니다 기능을 .

문자열 경우 다음 코드는 테스트 할 세 가지 목록 발현에 존재 | | | | 5 (파이프 " | "기호는 OR 논리 연산을 나타냄).

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

10g 버전부터 Oracle에서 사용 가능한 정규식 (REGEXP_ *)과 관련된 몇 가지 기능이 있습니다. Oracle 개발자이고이 주제에 관심이 있다면 Oracle Database에서 정규 표현식 사용을 시작하는 것이 좋습니다 .


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*"')

감사합니다. 허용되는 답변 IMO 여야합니다. 모든 사람이 정의 된 전문 색인을 가지고있는 것은 아닙니다. 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

나는 이것이 매우 늦다는 것을 알고 있지만 비슷한 상황이 있었다. 내가 가지고있는 일련의 저장 프로 시저에 대해 "좋아요"연산자가 필요했습니다.이 프로시 저는 많은 매개 변수를 허용 한 다음 해당 매개 변수를 사용하여 여러 RDBMS 시스템에서 데이터를 집계하므로 RDBMS 관련 트릭은 작동하지 않지만 저장 프로 시저 및 함수는 작동하지 않습니다. MS SQL Server에서 실행되므로 각 RDBMS에 대해 전체 SQL 문을 생성하는 기능에 T-SQL을 사용할 수 있지만 출력은 RDBMS와 무관해야합니다.

이것은 분리 된 문자열 (예 : 저장 프로 시저로 오는 매개 변수)을 SQL 블록으로 전환하는 순간에 내가 생각해 낸 것입니다. "LIKE IN"의 "이끼"라고합니다. 알 겠어요?

이끼 .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 매개 변수는 블록 앞에 선행 "AND"를 추가하여 다른 WHERE 절 추가에 잘 맞도록할지 결정하는 비트 값입니다.

사용법 예 (arrgString에 구분 기호 포함)

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

나는 이것에 대해 계속 연구 할 것이므로, (눈에 띄게 또는 다른 방식으로) 무언가를 간과했다면 자유롭게 의견을 말하거나 연락하십시오.


-3

이 작업을 수행

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

또는

WHERE something + '%' in (select col from table where ....)

1
어떻게 작동합니까? LHS는 %가 포함 된 문자열이므로 %는 와일드 카드가 아닙니다
Darius X.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.