bestsource

SQL에 'LIKE'와 'IN'의 조합이 있습니까?

bestsource 2023. 2. 28. 23:40
반응형

SQL에 'LIKE'와 'IN'의 조합이 있습니까?

I에서는 ( "SQL"을사용해야 하는 가 많습니다.LIKE거의 모든 정규화 규칙을 위반하는 데이터베이스로 인한 조건.★★★★★★★★★★★★★★★★★★★★★★★★★★★하지만 그것은 질문과는 무관합니다.

뿐만 아니라 '하다', '하다', '하다', '하다' 도 자주 합니다.WHERE something in (1,1,2,3,5,8,13,21)SQL 문의 가독성과 유연성을 향상시킬 수 있습니다.

복잡한 서브 셀렉트를 작성하지 않고 이 두 가지를 조합할 수 있는 방법이 있을까요?

는 그런 .WHERE something LIKE ('bla%', '%foo%', 'batz%') : 신 instead :

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

SQL Server와 Oracle을 사용하고 있습니다만, RDBMS에서 가능한지 알고 싶습니다.

SQL에는 LIKE와 IN의 조합이 없습니다.TSQL(SQL Server)이나 PLSQL(Oracle)은 말할 것도 없습니다.그 이유의 일부는 FTS(Full Text Search)가 권장되기 때문입니다.

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

Oracle:

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

SQL Server:

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

쿼리할 열은 전체 텍스트 색인화되어야 합니다.

레퍼런스:

쉽게 읽을 수 있도록 하려면 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_를 사용한 심플한 쿼리맘에 들다

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

SOMETH
------
blabla
ofooof
batzzz

3 rows selected.

그렇지만.....

성능이 좋지 않기 때문에 직접 추천하지 않습니다.나는 LIKE 술어 몇 개를 고수할 것이다.그래서 그 예시들은 단지 재미로 한 것이다.

당신은 그 일에 얽매여 있다.

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)

Postgre 포함SQL에는 또는 양식이 있습니다.

WHERE col LIKE ANY( subselect )

또는

WHERE col LIKE ALL( subselect )

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

다른 솔루션은 모든 RDB에서 작동해야 합니다.MS:

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)

내부 선택은 다음과 같은 방법으로 테이블(또는 뷰)과 같은 다른 패턴 소스로 대체할 수 있습니다.

WHERE EXISTS (SELECT 1
                FROM table_of_patterns t
               WHERE something LIKE t.pattern)

table_of_patterns.pattern을 사용하다

INSERT INTO table_of_patterns(pattern) VALUES ('bla%');
INSERT INTO table_of_patterns(pattern) VALUES ('%foo%');
INSERT INTO table_of_patterns(pattern) VALUES ('batz%');

위의 Inner Join 또는 temp table 기술을 캡슐화하고 싶다면 TableValue 사용자 기능을 사용하는 것이 좋습니다.이렇게 하면 좀 더 선명하게 읽을 수 있습니다.

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

"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파이크 2대7 앵글러8 월레아이

SQL Server와 Oracle을 사용하고 있습니다만, RDBMS에서 가능한지 알고 싶습니다.

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는 이러한 합성 술어를 즉시 지원할 수 있습니다.


SQLLIKE/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')

대신 내부 조인 사용:

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

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

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

적어도 postgresql에서 작동하는 간단한 솔루션이 있습니다.like any을 하다다음으로 리스트에서 항생제를 특정하는 예를 제시하겠습니다.

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

이것까지 시도해 볼 수 있다.

기능.

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

에는 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

저도 그런 게 궁금했어요. using금테테 using using using using using using using using using using using using using using using using를 요.SUBSTRING ★★★★★★★★★★★★★★★★★」IN그리고 그것은 이런 종류의 문제에 대한 효과적인 해결책이다.을 해보세요.

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

오라클에서는 다음과 같은 방법으로 컬렉션을 사용할 수 있습니다.

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);

이 솔루션은 SQL Server 2008에서만 사용할 수 있습니다.https://stackoverflow.com/a/7285095/894974에 설명되어 있는 행 구분자를 사용하여 like 절을 사용하여 'filk' 테이블에 가입할 수 있다는 것을 알게 되었습니다.더 복잡한 것처럼 들리네요. 보세요.

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

이것에 의해, 리스트에 기재되어 있는 것과 같은 전자 메일 주소를 가지는 모든 유저가 됩니다.누구에게나 유용했으면 좋겠다.그 문제가 한동안 나를 괴롭히고 있었다.

다음과 같은 조합을 생각할 수 있습니다.

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

SQL Server의 경우 동적 SQL을 사용할 수 있습니다.

대부분의 경우 데이터베이스의 일부 데이터를 기반으로 IN 절 매개 변수를 사용합니다.

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

[개인명(Person Name)]테이블이 있는 경우 [개인명(Persons)]에는 [이름(FirstName)]+ [이름(First Name)]+ [성(Last Name)]라고 표시됩니다.테이블의 NameToSelect 필드에 저장된 이름 목록에서 모든 사용자를 선택해야 합니다.To Select(선택 방법) 및 몇 가지 추가 기준(성별, 생년월일 등에 따라 필터링됨)

다음과 같이 할 수 있습니다.

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

MySQL을 사용하는 경우 전체 텍스트 검색에서 가장 가까운 값을 얻을 수 있습니다.

전체 텍스트 검색, MySQL 문서

이것은 쉼표로 구분된 값에 대해 작동합니다.

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

인덱스를 사용하려면 첫 번째 항목을 생략해야 합니다.'%'성격.

Oracle RBDMS에서는 REGEXP_LIKE 함수를 사용하여 이 동작을 실행할 수 있습니다.

다음 코드는 문자열 3이 목록 1|2|3|4|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에서 정규 표현식 사용을 시작하는 것이 좋습니다.

다음과 같은 답변 없음:

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

오라클에서는 문제 없습니다.

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

오래된 게시물을 들춰내서 미안하지만, 조망권이 많아요.이번 주에도 비슷한 문제에 직면하여 다음과 같은 패턴을 생각해 냈습니다.

declare @example table ( sampletext varchar( 50 ) );

insert @example values 
( 'The quick brown fox jumped over the lazy dog.' ),
( 'Ask not what your country can do for you.' ),
( 'Cupcakes are the new hotness.' );

declare @filter table ( searchtext varchar( 50 ) );

insert @filter values
( 'lazy' ),
( 'hotness' ),
( 'cupcakes' );

-- Expect to get rows 1 and 3, but no duplication from Cupcakes and Hotness
select * 
from @example e
where exists ( select * from @filter f where e.sampletext like '%' + searchtext + '%' )

Exists()는 join(IMO)보다 조금 더 잘 동작합니다.이는 세트 내의 각 레코드를 테스트하는 것일 뿐 여러 개의 일치가 있어도 중복이 발생하지 않기 때문입니다.

에서 Postgres를 사용하여 합니다.like ★★★★★★★★★★★★★★★★★」ilike ★★★★★★★★★★★★★★★★★」any ★★★★★★★★★★★★★★★★★」allarray다음 예시는 Postgres 9를 사용하는 데 도움이 됩니다.

select id, name from tb_organisation where name ilike any (array['%wembley%', '%south%']);

다음과 같이 출력됩니다.

id | 이름-----+------------------------433 | 사우스탬파 센터613 | 남극365 | 브롬리 사우스796 | 웸블리 특별 이벤트202 | 사우스올111 | 웸블리 내부 공간

»T-SQL 이. , , , , , , , , , , , , , , , , , , , , , ,

CREATE FUNCTION FN_LIKE_IN (@PROC NVARCHAR(MAX), @ITENS NVARCHAR(MAX)) RETURNS NVARCHAR(MAX) AS BEGIN
    
        --Search an item with LIKE inside a list delimited by "," Vathaire 11/06/2019
    
    DECLARE @ITEM NVARCHAR(MAX)
    WHILE CHARINDEX(',', @ITENS) > 0 BEGIN
        SET @ITEM = LEFT(@ITENS, CHARINDEX(',', @ITENS) - 1)
        --IF @ITEM LIKE @PROC
        IF @PROC LIKE @ITEM
            RETURN @PROC --@ITEM --1
        ELSE
            SET @ITENS = STUFF(@ITENS, 1, LEN(@ITEM) + 1, '')
    END
    IF @PROC LIKE @ITENS RETURN @PROC --@ITEM --1
    RETURN NULL --0
END

쿼리:

SELECT * FROM SYS.PROCEDURES
WHERE DBO.FN_LIKE_IN(NAME, 'PRC%,SP%') IS NOT NULL

퍼포먼스를 희생하면서 많은 요소에 대해 동적으로 이 작업을 수행할 수 있지만, 동작합니다.

DECLARE @val nvarchar(256),
@list nvarchar(max) = 'one,two,three,ten,five';
CREATE table #table  (FIRST_NAME nvarchar(512), LAST_NAME nvarchar(512));
CREATE table #student  (FIRST_NAME nvarchar(512), LAST_NAME nvarchar(512), EMAIL 
nvarchar(512));
INSERT INTO #student (FIRST_NAME, LAST_NAME, EMAIL)
SELECT 'TEST', ' redOne' ,'test.redOne@toto.com' UNION ALL
SELECT 'student', ' student' ,'student@toto.com' UNION ALL
SELECT 'student', ' two' ,'student.two@toto.com' UNION ALL
SELECT 'hello', ' ONE TWO THREE' ,'student.two@toto.com'

DECLARE check_cursor CURSOR FOR select value from STRING_SPLIT(@list,',')

OPEN check_cursor  
FETCH NEXT FROM check_cursor INTO @val
WHILE @@FETCH_STATUS = 0  
    BEGIN
     PRINT @val
       IF EXISTS (select * from #student where REPLACE(FIRST_NAME, ' ','') 
like '%' + @val + '%' OR REPLACE(LAST_NAME, ' ','') like '%' + @val + '%') 
       BEGIN
       INSERT INTO #table (FIRST_NAME, LAST_NAME )
       SELECT TOP 1 FIRST_NAME, LAST_NAME VALUE from #student where 
REPLACE(FIRST_NAME, ' ','') like '%' + @val + '%' OR REPLACE(LAST_NAME, ' ','') 
like '%' + @val + '%'
       END;

      FETCH NEXT FROM check_cursor INTO @val 
    END
CLOSE check_cursor;  
DEALLOCATE check_cursor;  

SELECT * FROM #table;
DROP TABLE #table;
DROP TABLE #student;

SQL SERVER에서 커서를 사용하여 모든 값에 대해 실행합니다.

테이블 샘플:

 create table Gastos_ConciliacionExcluida(IdRegistro int identity(1,1), MascaraTexto nvarchar(50), Activa bit default 1, Primary key (IDRegistro))


insert into Gastos_ConciliacionExcluida(MascaraTexto) Values ('%Reembolso%')



alter procedure SP_Gastos_ConciliacionExcluidaProcesar
as

declare cur cursor for select MascaraTexto From Gastos_ConciliacionExcluida where Activa=1
declare @Txt nvarchar(50)

open cur

fetch next from cur into @Txt
while @@Fetch_Status = 0
begin
    update Gastos_BancoRegistro set PresumibleNoConciliable = 1 
    where   Concepto like @txt
    fetch next from cur into @Txt
end 
close cur
deallocate cur

이것을 하다

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

또는

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

언급URL : https://stackoverflow.com/questions/3014940/is-there-a-combination-of-like-and-in-in-sql

반응형