MySQL처럼 ()?


273

내 현재 쿼리는 다음과 같습니다.

SELECT * FROM fiberbox f WHERE f.fiberBox LIKE '%1740 %' OR f.fiberBox LIKE '%1938 %' OR f.fiberBox LIKE '%1940 %'

나는 주변을 둘러 보았고 LIKE IN ()과 비슷한 것을 찾을 수 없었습니다.

SELECT * FROM fiberbox f WHERE f.fiberbox LIKE IN('%140 %', '%1938 %', '%1940 %')

어떤 아이디어? 나는 단지 문제를 잘못된 길로 생각하고 있습니까?

MySQL 5.0.77- 커뮤니티-로그


1
WHERE FIND_IN_SET(f.fiberbox, "1740,1938,1940")
Gjermund Dahl

2
FIND_IN_SET처럼 와일드 카드를 허용하지 않습니다%
세바스티안 Grignoli

답변:


454

정규 표현식이 있습니다 더 효율적일 수 있지만, 당신은 확실히 예로 벤치 마크해야 할 것

SELECT * from fiberbox where field REGEXP '1740|1938|1940'; 

2
나는이 대답을 좋아합니다-빠르고 간단하며 원하는대로 한 줄로 모든 "옵션"을 얻었습니다 (편집하기 쉽습니다). 작은 결과 집합에서 타겟팅하고있어 성능 저하가 전혀 없습니다.
Michael Wales

51
내 테이블에 백만 개가 넘는 행이 있습니다. REGEX arround 0.0009 및 LIKE arround 0.0005. 더 후 5 REGEX 경우 ... 0.0012을 arround를
데이비드 Belanger 보낸 사람에게

10
나는 REGEXP엄청나게 느린 문제가 있었지만 REGEXP의 유연성이 필요했기 때문에 결과 세트를 LIKE제공 할 수있는 것보다 더 좁혔습니다 . 나는 둘 다 사용하는 하이브리드 솔루션을 내놓았다 LIKEREGEXP; REGEXP나에게 정확한 결과를 제공하기에 충분한 부분 에도 불구하고, LIKEMySQL을 사용하면 더 느리게 사용하기 전에 결과 세트를 상당히 줄일 수있었습니다.REGEXP 기준.
mpen

1
열에서 정규 표현식 값을 가져 오려면 :(select group_concat(myColumn separator '|') from..)
daVe

5
성능 데이터에 추가 229M 개의 행이있는 테이블의 MySql 5.5에서 1 개의 용어가 고정 된 3 자 검색 : REGEXP : 16s, LIKE : 8.5s; 2 개의 용어 : REGEXP : 22.1s, LIKE : 9.69; '^ (헤모글로빈 | 혈액? ocrit). *'vs. 3과 같은 용어 : REGEXP : 36.3, LIKE : 9.59.
Jesse Clark

181

폴 딕슨의 대답은 저에게 훌륭하게 작용했습니다. 여기에 REGEXP 사용에 관심이있는 사람들이 관찰 한 사항이 있습니다.

와일드 카드로 여러 LIKE 필터를 달성하려면 다음을 수행하십시오.

 SELECT * FROM fiberbox WHERE field LIKE '%1740 %'
                           OR field LIKE '%1938 %'
                           OR field LIKE '%1940 %';  

REGEXP 대안 사용 :

 SELECT * FROM fiberbox WHERE field REGEXP '1740 |1938 |1940 ';

REGEXP 따옴표 안의 값과 | (또는) 연산자는 와일드 카드로 취급됩니다. 일반적으로 REGEXP는 % 1740 %로 작동하려면 (. *) 1740 (. *)과 같은 와일드 카드식이 필요합니다.

와일드 카드 배치를보다 세밀하게 제어해야하는 경우 다음 변형 중 일부를 사용하십시오.

제어 된 와일드 카드 배치로 LIKE를 달성하려면 다음을 수행하십시오.

SELECT * FROM fiberbox WHERE field LIKE '1740 %'
                          OR field LIKE '%1938 '
                          OR field LIKE '%1940 % test';  

사용하다:

SELECT * FROM fiberbox WHERE field REGEXP '^1740 |1938 $|1940 (.*) test';
  • 값 앞에 ^를두면 줄의 시작을 나타냅니다.

  • 값 뒤에 $를두면 줄의 끝을 나타냅니다.

  • 배치 (. *)는 % 와일드 카드와 매우 유사하게 작동합니다.

  • . 줄 바꿈을 제외한 모든 단일 문자를 나타냅니다. 배치. inside () with * (. *)는 줄 끝까지 문자 수를 나타내는 반복 패턴을 추가합니다.

특정 일치 항목의 범위를 좁히는 더 효율적인 방법이 있지만 정규 표현식을 더 많이 검토해야합니다. 참고 : 모든 정규식 패턴이 MySQL 문에서 작동하는 것으로 보이지는 않습니다. 패턴을 테스트하고 효과가 있는지 확인해야합니다.

마지막으로 여러 개의 LIKE 및 NOT LIKE 필터를 달성하려면 다음을 수행하십시오.

SELECT * FROM fiberbox WHERE field LIKE '%1740 %'
                          OR field LIKE '%1938 %'
                          OR field NOT LIKE '%1940 %'
                          OR field NOT LIKE 'test %'
                          OR field = '9999';

REGEXP 대안 사용 :

SELECT * FROM fiberbox WHERE field REGEXP '1740 |1938 |^9999$'
                          OR field NOT REGEXP '1940 |^test ';

또는 혼합 대안 :

SELECT * FROM fiberbox WHERE field REGEXP '1740 |1938 '
                          OR field NOT REGEXP '1940 |^test '
                          OR field NOT LIKE 'test %'
                          OR field = '9999';

별도의 WHERE 필터에서 NOT 설정을 분리했습니다. 부정적 패턴, 미래 지향적 패턴 등을 사용하여 실험했습니다. 그러나 이러한 표현은 원하는 결과를 얻지 못했습니다. 위의 첫 번째 예에서는 ^ 9999 $를 사용하여 정확하게 일치 함을 나타냅니다. 이렇게하면 동일한 식에서 와일드 카드 일치를 사용하여 특정 일치를 추가 할 수 있습니다. 그러나 나열된 두 번째 예에서 볼 수 있듯이 이러한 유형의 명령문을 혼합 할 수도 있습니다.

성능과 관련하여 기존 테이블에 대해 몇 가지 사소한 테스트를 실행했으며 변형간에 차이가 없었습니다. 그러나 더 큰 데이터베이스, 더 큰 필드, 더 많은 레코드 수 및 더 복잡한 필터에서는 성능이 문제가 될 수 있다고 생각합니다.

항상 그렇듯이 위의 논리를 사용하는 것이 좋습니다.

정규식에 대한 자세한 내용을 보려면 www.regular-expressions.info를 좋은 참조 사이트로 권장합니다.


NULL 값을 가진 필드는 REGEXP와 일치하지 않습니다. IFNULL을 사용하여이 문제를 해결할 수 있습니다. WHERE IFNULL(field, '') NOT REGEXP '1740 | 1938'

@DanyMarcoux (. *)를 사용하고 싶지만 FIELDNAME LIKE '%%'처럼 작동해야하는 경우 빈 문자열이 전달 될 때 regexp와 함께 사용하는 방법. 그것은 모든 기록을 가져와야한다.
shzyincu

'% 1940 %'와 같은 NOT WHERE 필드 또는 'test %'와 같은 NOT 필드는 항상 모든 행을 반환합니다. 그것은 아마도 당신이 언급 한 원하는 결과를 얻지 못하는 데 기여했을 수 있습니까?
Herbert Van-Vliet

14

인라인 뷰 또는 임시 테이블을 작성하고 값으로 채우고 다음을 발행 할 수 있습니다.

SELECT  *
FROM    fiberbox f
JOIN    (
        SELECT '%1740%' AS cond
        UNION ALL
        SELECT '%1938%' AS cond
        UNION ALL
        SELECT '%1940%' AS cond
        ) с
ON      f.fiberBox LIKE cond

이것은, 그러나, 당신에게 여러 행을 반환 할 수 있습니다 fiberbox같은입니다 '1740, 1938'이 쿼리가 더 잘 들어갈 수 있도록 :

SELECT  *
FROM    fiberbox f
WHERE   EXISTS
        (
        SELECT  1
        FROM    (
                SELECT '%1740%' AS cond
                UNION ALL
                SELECT '%1938%' AS cond
                UNION ALL
                SELECT '%1940%' AS cond
                ) с
        WHERE   f.fiberbox LIKE cond
        )

13

값 목록이있는 정규 표현식

SELECT * FROM table WHERE field regexp concat_ws("|",
"111",
"222",
"333");

7

죄송합니다. 비슷한 작업이 없습니다 LIKE IN mysql .

조인없이 LIKE 연산자를 사용하려면 다음과 같이해야합니다.

(field LIKE value OR field LIKE value OR field LIKE value)

MySQL은 해당 쿼리를 최적화하지 않습니다.


4

REGEXP를 "LIKE IN"기능을 사용하려고하는 사람에게만주의하십시오.

IN을 사용하면 다음을 수행 할 수 있습니다.

field IN (
'val1',
'val2',
'val3'
)

REGEXP에서는 작동하지 않습니다

REGEXP '
val1$|
val2$|
val3$
'

다음과 같이 한 줄에 있어야합니다.

REGEXP 'val1$|val2$|val3$'

3

피연산자 뒤집기

'a,b,c' like '%'||field||'%'

2
어떤 필드가있을 때 명시 적으로 같은 것이 될 것입니다. 졸업생을위한 열거 , 'B', 'C' 'A' 가 아니라 AB, AC 또는 BC create table x(en enum('a,b,c')));insert into x values('a'),('b') 욕실이 아니라 A 또는 B oprands을 틀지하여이 방법을 수행하기 select * from, x where 'a,c' like concat('%',en,'%')에 안전 할 수 없다 SQL 금지 명령 등의 charactors 탈출 할 필요 $를 ^ 등

이것은 동일하지 않으며 일반적인 경우에는 작동하지 않습니다. 당신이 알았다면 그 field에만 정확하게 할 수있다 a, b또는 c당신은 사용해야합니다 field IN ('a', 'b', 'c'). 그러나 일반적인 경우에,이 대체 할 수 없다 field LIKE '%a%' OR field LIKE '%b%' OR ...필드 자체가 같은 수 있기 때문에 magic만들 것 'magic' LIKE '%a%'사실이지만 표현의 'a,b,c' LIKE '%magic%'거짓.
ADTC

2

이것은 맞을 것입니다 :

SELECT * FROM table WHERE field regexp concat_ws("|",(
"111",
"222",
"333"
));

2

작은 팁 :

나는 RLIKE ( REGEXP 와 정확히 같은 명령) 변형을 사용하는 것이 더 자연스럽고 짧습니다. 글쎄, 단지 1 문자입니다.

"R"접두사는 Reg. 물론입니다.


0

정규 표현식의 도움으로 원하는 결과를 얻을 수 있습니다 .

SELECT fiberbox from fiberbox where fiberbox REGEXP '[1740|1938|1940]';

우리는 위의 쿼리를 테스트 할 수 있습니다 SQL 바이올린을 클릭하십시오

SELECT fiberbox from fiberbox where fiberbox REGEXP '[174019381940]';

우리는 위의 쿼리를 테스트 할 수 있습니다 SQL 바이올린을 클릭하십시오


1
이것은 잘못된 정규식입니다. [...]문자 집합으로 , 집합의 모든 문자가 일치하는 것으로 보일 정도로 충분합니다. 그래서 숫자와 ' 0, 1, 3, 4, 7, 8, 9또는 |파이프 문자는이 일치합니다.
Martijn Pieters
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.