- 카테고리:
문자열 및 이진 함수 (전체 텍스트 검색)
SEARCH¶
VARIANT, OBJECT 및 ARRAY 열의 필드를 포함하여 하나 이상의 테이블에서 지정된 열의 문자 데이터(텍스트)를 검색합니다. 텍스트 분석기는 텍스트를 토큰으로 분석하는데, 토큰은 단어나 숫자와 같은 개별 텍스트 단위입니다. 분석기를 지정하지 않으면 기본 분석기가 적용됩니다.
이 함수를 사용하는 방법에 대한 자세한 내용은 전체 텍스트 검색 사용하기 섹션을 참조하십시오.
구문¶
SEARCH( <search_data>, <search_string> [ , ANALYZER => '<analyzer_name>' ] )
인자¶
search_data
검색하려는 데이터는 문자열 리터럴, 열 이름 또는 VARIANT 열의 필드에 대한 경로 를 쉼표로 구분된 목록으로 표현됩니다. 검색 데이터는 단일 리터럴 문자열이 될 수도 있는데, 이는 함수를 테스트할 때 유용할 수 있습니다.
와일드카드 문자(
*
)를 지정할 수 있는데, 여기서*
는 함수 범위에 있는 모든 테이블에 있는 모든 적격 열로 확장됩니다. 적격 열은 VARCHAR(텍스트), VARIANT, ARRAY, OBJECT 데이터 타입을 갖는 열입니다. VARIANT, ARRAY 및 OBJECT 데이터는 검색을 위해 텍스트로 변환됩니다.함수에 와일드카드를 전달할 때 와일드카드를 테이블의 이름이나 별칭으로 한정할 수 있습니다. 예를 들어,
mytable
이라는 테이블의 모든 열을 전달하려면 다음을 지정하십시오.(mytable.*)
필터링을 위해 ILIKE 및 EXCLUDE 키워드를 사용할 수도 있습니다.
ILIKE는 지정된 패턴과 일치하는 열 이름을 필터링합니다. 패턴은 하나만 허용됩니다. 예:
(* ILIKE 'col1%')
EXCLUDE는 지정된 열과 일치하지 않는 열 이름을 걸러냅니다. 예:
(* EXCLUDE col1) (* EXCLUDE (col1, col2))
이러한 키워드를 사용할 경우 한정자가 유효합니다. 다음 예에서는 ILIKE 키워드를 사용하여 테이블
mytable
의 패턴col1%
와 일치하는 모든 열을 필터링합니다.(mytable.* ILIKE 'col1%')
ILIKE 및 EXCLUDE 키워드는 단일 함수 호출에서 결합할 수 없습니다.
ILIKE 및 EXCLUDE 키워드에 대한 자세한 내용은 SELECT 의 “매개 변수” 섹션을 참조하십시오.
테이블을 조인하거나 UNION 세트 연산자를 사용함으로써 여러 테이블이 범위에 있는 경우 2개 이상의 테이블에서 열을 검색할 수 있습니다. 조인이나 UNION 쿼리의 출력에서 모든 열을 검색하려면 다음과 같이 정규화되지 않은
*
와일드카드를 사용할 수 있습니다.SELECT * FROM t AS T1 JOIN t AS T2 USING (col1) WHERE SEARCH((*), 'string');
테이블을 조인할 때 특정 열을 검색하려면 열 이름(예:
table2.colname
)을 한정해야 할 수도 있습니다. 다음과 같이 정규화된*
와일드카드를 사용할 수도 있습니다.SELECT * FROM t AS T1 JOIN t AS T2 USING (col1) WHERE SEARCH((T2.*), 'string');
하지만 함수에 대해
*
또는table.*
을 두 번 이상 지정할 수 없습니다. 이전 조인 예에서는SEARCH((T1.*, T2.*), 'string')
을 지정할 수 없습니다. 이 구문은 오류를 반환합니다.*
,table.*
또는 여러 항목이 나열된 경우search_data
인자에 괄호가 필요합니다. 예:SEARCH((col1, col2, col3), 'string') SEARCH((t1.*), 'string') SEARCH((*), 'string')
괄호를 사용하여 여러 항목을 구분하지 않을 경우 쉼표는 함수 인자 사이의 구분 기호로 구문 분석됩니다.
예상되는 오류 사례의 예 섹션도 참조하십시오.
열 이름, 콜론이나 점, 점으로 구분된 하위 필드를 지정하여 VARIANT 데이터의 필드를 검색할 수 있습니다. 예를 들어
colname:fieldname.subfieldname
과 같습니다. 이러한 열에 필드를 지정하는 방법에 대한 자세한 내용은 반정형 데이터 탐색하기 섹션을 참조하십시오.search_string
하나 이상의 검색어가 포함된 VARCHAR 문자열입니다. 이 인자는 리터럴 문자열이어야 하며, 열 이름은 지원되지 않습니다. 전체 문자열을 작은따옴표 한 쌍으로 묶어 지정합니다. 개별 용어나 문구를 따옴표로 묶지 지정하지는 마십시오. 예를 들어 다음을 사용하십시오.
'blue red green'
다음은 사용하지 마십시오.
'blue' 'red' 'green'
검색어 목록은 분리적입니다. 이 경우, 검색은
blue
ORred
ORgreen
을 포함하는 행을 찾습니다. 그러나 NO_OP_ANALYZER를 사용하는 경우 쿼리 문자열은 토큰화나 분리적 의미 없이 정확히 그대로 일치 여부를 판단합니다.검색은 대/소문자를 구분하지 않으므로(NO_OP_ANALYZER가 사용된 경우는 제외) 문자열
'Once upon a time'
에 대해'ONCE'
라는 검색어를 검색하면 TRUE가 반환됩니다.검색된 데이터에서 검색어의 존재 여부와 관련하여 검색어의 순서는 중요하지 않습니다.
ANALYZER => 'analyzer_name'
텍스트 분석기의 이름을 지정하는 선택적 인자입니다. 이름은 작은따옴표로 묶어야 합니다.
분석기는 검색어와 검색 중인 열의 텍스트를 토큰으로 분리합니다. 검색 문자열에서 추출된 토큰 중 하나가 검색 중인 열이나 필드에서 추출된 토큰과 일치하면 행이 정확히 일치하는 것입니다.
분석기는 특정 구분 기호를 발견한 문자열을 끊어 토큰화합니다. 이러한 구분 기호는 결과 토큰에 포함되지 않으며, 빈 토큰은 추출되지 않습니다.
이 매개 변수는 다음 값 중 하나를 허용합니다.
DEFAULT_ANALYZER: 다음 구분 기호를 기준으로 텍스트를 토큰으로 분리합니다.
문자
유니코드 코드
설명
U+0020
공백
[
U+005B
왼쪽 대괄호
]
U+005D
오른쪽 대괄호
;
U+003B
세미콜론
<
U+003C
보다 작음 기호
>
U+003E
보다 큼 기호
(
U+0028
왼쪽 괄호
)
U+0029
오른쪽 괄호
{
U+007B
왼쪽 중괄호
}
U+007D
오른쪽 중괄호
|
U+007C
세로선
!
U+0021
느낌표
,
U+002C
쉼표
'
U+0027
아포스트로피
"
U+0022
따옴표
*
U+002A
별표
&
U+0026
앰퍼샌드
?
U+003F
물음표
+
U+002B
더하기 기호
/
U+002F
슬래시
:
U+003A
콜론
=
U+003D
등호
@
U+0040
@ 기호
.
U+002E
마침표
-
U+002D
하이픈
$
U+0024
달러 기호
%
U+0025
퍼센트 기호
\
U+005C
백슬래시
_
U+005F
밑줄
\n
U+000A
줄 바꿈
\r
U+000D
캐리지 리턴
\t
U+0009
가로 탭
UNICODE_ANALYZER: 공백과 특정 구두점 문자를 구분 기호로 처리하는 유니코드 분할 규칙에 따라 토큰화합니다. 이러한 내부 규칙은 (다양한 언어로) 자연어 검색을 할 수 있도록 설계되었습니다. 예를 들어, 기본 분석기는 IP 주소의 마침표와 축약형의 아포스트로피를 구분 기호로 처리하지만 유니코드 분석기는 그렇지 않습니다. 분석기를 사용하여 검색 동작 조정하기 섹션을 참조하십시오.
유니코드 텍스트 분할 알고리즘에 대한 자세한 내용은 https://unicode.org/reports/tr29/를 참조하십시오.
NO_OP_ANALYZER: 데이터나 쿼리 문자열을 토큰화하지 않습니다. 검색어는 대/소문자 일치를 포함하여 열이나 필드의 전체 텍스트와 정확하게 일치해야 하며, 그렇지 않을 경우 SEARCH 함수는 FALSE를 반환합니다. 쿼리 문자열에 여러 가지 토큰(예:
'sky blue'
)이 포함된 것처럼 보이더라도 열이나 필드가 전체 쿼리 문자열과 정확히 같아야 합니다. 이 경우에는'sky blue'
만 일치하고'sky'
와'blue'
는 일치하지 않습니다.
다양한 분석기의 동작에 대한 자세한 내용은 검색어 토큰화 방식 섹션을 참조하십시오.
반환¶
BOOLEAN 을 반환합니다.
search_data
에서search_string
토큰이 발견되면 값은 TRUE입니다.이러한 인자 중 하나가 NULL이면 NULL을 반환합니다.
그렇지 않으면 FALSE를 반환합니다.
사용법 노트¶
SEARCH 함수는 VARCHAR, VARIANT, ARRAY 및 OBJECT 데이터에 대해서만 작동합니다.
search_data
인자에 이러한 데이터 타입의 데이터가 포함되지 않은 경우 함수는 오류를 반환합니다.search_data
인자에 지원되는 데이터 타입과 지원되지 않는 데이터 타입의 데이터가 모두 포함된 경우, 함수는 지원되는 데이터 타입의 데이터를 검색하고 지원되지 않는 데이터 타입의 데이터는 자동으로 무시합니다. 예는 예상되는 오류 사례의 예 을 참조하십시오.ALTER TABLE 명령을 사용하여 SEARCH 함수 호출의 대상이 되는 열에 FULL_TEXT 검색 최적화를 추가할 수 있습니다. 예:
ALTER TABLE lines ADD SEARCH OPTIMIZATION ON FULL_TEXT(play, character, line);
자세한 내용은 FULL_TEXT 검색 최적화 사용하기 섹션을 참조하십시오.
검색어 토큰화 방식¶
다음 표에는 사용되는 분석기에서 적용하는 규칙에 따라 입력 검색어가 토큰으로 분할되는 방식을 보여주는 몇 가지 예가 나와 있습니다. 표에서 쉼표는 토큰이 분할된 위치를 나타냅니다(있는 경우).
검색어 |
토큰: DEFAULT_ANALYZER |
토큰: UNICODE_ANALYZER |
NO_OP_ANALYZER(분할되지 않음) |
---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
예¶
다음에 나오는 예에서는 SEARCH 함수를 사용하는 다양한 방법을 보여주는데, 먼저 간단한 사용 사례부터 시작해 보다 복잡한 사용 사례로 진행됩니다.
리터럴에 대한 일치¶
SEARCH 함수의 가장 간단한 예는 문자열 리터럴에서 TRUE 또는 FALSE를 테스트하는 것입니다. 첫 번째 예에서는 첫 번째 인자와 두 번째 인자의 리터럴이 일치하므로 TRUE를 반환하는데, 비교 시 대/소문자를 구분하지 않습니다.
SELECT SEARCH('king','KING');
+-----------------------------+
| SEARCH('KING','KING') |
|-----------------------------|
| True |
+-----------------------------+
두 번째 예에서는 토큰 32
가 첫 번째 인자에 지정된 리터럴 5.1.33
에 나타나지 않으므로 FALSE를 반환합니다.
SELECT SEARCH('5.1.33','32');
+-----------------------------+
| SEARCH('5.1.33','32') |
|-----------------------------|
| False |
+-----------------------------+
열 참조에 대한 일치¶
이 예에서는 테이블의 열을 첫 번째 인자로 사용합니다. 검색어 중 하나(king
)가 character
열에 존재하므로 이 함수는 TRUE를 반환합니다. 검색어 목록은 분리적입니다. (이 예와 뒤에 나오는 몇몇 예에서 사용되는 테이블에 대한 자세한 내용은 SEARCH에 대한 샘플 데이터 섹션을 참조하십시오.)
SELECT SEARCH(character, 'king queen'),character
FROM lines
WHERE line_id=4;
+--------------------------------------+---------------+
| SEARCH(CHARACTER,'KING QUEEN') | CHARACTER |
|--------------------------------------+---------------|
| True | KING HENRY IV |
+--------------------------------------+---------------+
한 열에 대한 WHERE 절 검색¶
다음 쿼리에서는 SEARCH 함수를 사용하여 line
열에 “wherefore”라는 단어가 포함된 행을 찾습니다.
SELECT *
FROM lines
WHERE SEARCH(line, 'wherefore')
ORDER BY character LIMIT 5;
+---------+----------------------+------------+----------------+-----------+-----------------------------------------------------+
| LINE_ID | PLAY | SPEECH_NUM | ACT_SCENE_LINE | CHARACTER | LINE |
|---------+----------------------+------------+----------------+-----------+-----------------------------------------------------|
| 100109 | Troilus and Cressida | 31 | 2.1.53 | ACHILLES | Why, how now, Ajax! wherefore do you thus? How now, |
| 16448 | As You Like It | 2 | 2.3.6 | ADAM | And wherefore are you gentle, strong and valiant? |
| 24055 | The Comedy of Errors | 14 | 5.1.41 | AEMELIA | Be quiet, people. Wherefore throng you hither? |
| 99330 | Troilus and Cressida | 30 | 1.1.102 | AENEAS | How now, Prince Troilus! wherefore not afield? |
| 92454 | The Tempest | 150 | 2.1.343 | ALONSO | Wherefore this ghastly looking? |
+---------+----------------------+------------+----------------+-----------+-----------------------------------------------------+
여러 열에 대한 WHERE 절 검색¶
다음 쿼리에서는 SEARCH 함수를 사용하여 play
열, character
열 또는 두 열 모두에 “king”이라는 단어가 포함된 행을 찾습니다. 첫 번째 인자에는 괄호가 필요합니다.
SELECT play, character
FROM lines
WHERE SEARCH((play, character), 'king')
ORDER BY play, character LIMIT 10;
+---------------------------+-----------------+
| PLAY | CHARACTER |
|---------------------------+-----------------|
| All's Well That Ends Well | KING |
| Hamlet | KING CLAUDIUS |
| Hamlet | KING CLAUDIUS |
| Henry IV Part 1 | KING HENRY IV |
| Henry IV Part 1 | KING HENRY IV |
| King John | CHATILLON |
| King John | KING JOHN |
| King Lear | GLOUCESTER |
| King Lear | KENT |
| Richard II | KING RICHARD II |
+---------------------------+-----------------+
테이블의 모든 적격 열에 대한 와일드카드 검색¶
이 예에서 보듯이 *
문자(또는 table.*
)를 SEARCH 함수의 첫 번째 인자로 사용할 수 있습니다. 검색은 선택하는 테이블의 모든 적격 열(이 경우에는 lines
테이블)에서 수행됩니다.
lines
테이블에는 검색 기능에서 지원되는 데이터 타입을 가진 열이 4개 있습니다. 결과는 검색된 4개 열 중 하나 이상에 “king”이 나타나는 행으로 구성됩니다. 이러한 열 중 하나인 act_scene_line
의 경우 함수가 일치 항목을 찾지 못했지만 다른 세 열에는 모두 일치 항목이 있습니다.
SELECT play, character, line, act_scene_line
FROM lines
WHERE SEARCH((lines.*), 'king')
ORDER BY act_scene_line LIMIT 10;
+-----------------+-----------------+----------------------------------------------------+----------------+
| PLAY | CHARACTER | LINE | ACT_SCENE_LINE |
|-----------------+-----------------+----------------------------------------------------+----------------|
| Pericles | LODOVICO | This king unto him took a fere, | 1.0.21 |
| Richard II | KING RICHARD II | Old John of Gaunt, time-honour'd Lancaster, | 1.1.1 |
| Henry VI Part 3 | WARWICK | I wonder how the king escaped our hands. | 1.1.1 |
| King John | KING JOHN | Now, say, Chatillon, what would France with us? | 1.1.1 |
| King Lear | KENT | I thought the king had more affected the Duke of | 1.1.1 |
| Henry IV Part 1 | KING HENRY IV | So shaken as we are, so wan with care, | 1.1.1 |
| Henry IV Part 1 | KING HENRY IV | Which, like the meteors of a troubled heaven, | 1.1.10 |
| King Lear | GLOUCESTER | so often blushed to acknowledge him, that now I am | 1.1.10 |
| Cymbeline | First Gentleman | Is outward sorrow, though I think the king | 1.1.10 |
| King John | CHATILLON | To this fair island and the territories, | 1.1.10 |
+-----------------+-----------------+----------------------------------------------------+----------------+
필터링에 ILIKE 및 EXCLUDE 키워드를 사용할 수도 있습니다. 이러한 키워드에 대한 자세한 내용은 SELECT 섹션을 참조하십시오.
이 검색에서는 ILIKE 키워드를 사용하여 문자열 line
으로 끝나는 열에서만 검색합니다.
SELECT play, character, line, act_scene_line
FROM lines
WHERE SEARCH((lines.* ILIKE '%line'), 'king')
ORDER BY act_scene_line LIMIT 10;
+-----------------+-----------------+--------------------------------------------------+----------------+
| PLAY | CHARACTER | LINE | ACT_SCENE_LINE |
|-----------------+-----------------+--------------------------------------------------+----------------|
| Pericles | LODOVICO | This king unto him took a fere, | 1.0.21 |
| Henry VI Part 3 | WARWICK | I wonder how the king escaped our hands. | 1.1.1 |
| King Lear | KENT | I thought the king had more affected the Duke of | 1.1.1 |
| Cymbeline | First Gentleman | Is outward sorrow, though I think the king | 1.1.10 |
+-----------------+-----------------+--------------------------------------------------+----------------+
이 검색에서는 EXCLUDE 키워드를 사용하므로 함수가 character
열의 데이터를 검색하지 않습니다.
SELECT play, character, line, act_scene_line
FROM lines
WHERE SEARCH((lines.* EXCLUDE character), 'king')
ORDER BY act_scene_line LIMIT 10;
+-----------------+-----------------+----------------------------------------------------+----------------+
| PLAY | CHARACTER | LINE | ACT_SCENE_LINE |
|-----------------+-----------------+----------------------------------------------------+----------------|
| Pericles | LODOVICO | This king unto him took a fere, | 1.0.21 |
| Henry VI Part 3 | WARWICK | I wonder how the king escaped our hands. | 1.1.1 |
| King John | KING JOHN | Now, say, Chatillon, what would France with us? | 1.1.1 |
| King Lear | KENT | I thought the king had more affected the Duke of | 1.1.1 |
| Cymbeline | First Gentleman | Is outward sorrow, though I think the king | 1.1.10 |
| King Lear | GLOUCESTER | so often blushed to acknowledge him, that now I am | 1.1.10 |
| King John | CHATILLON | To this fair island and the territories, | 1.1.10 |
+-----------------+-----------------+----------------------------------------------------+----------------+
SELECT 목록에서의 와일드카드 검색¶
다음 예에서 보듯이, SELECT 목록에서 *
문자(또는 table.*
)를 사용할 수 있습니다.
다음 검색은 선택하는 테이블의 모든 적격 열(이 경우에는 lines
테이블)에서 수행됩니다. 검색된 4개 열 중 하나 이상에 “king”이 나타나면 검색 결과에 True
가 반환됩니다.
SELECT SEARCH((*), 'king') result, *
FROM lines
ORDER BY act_scene_line LIMIT 10;
+--------+---------+---------------------------+------------+----------------+-----------------+--------------------------------------------------------+
| RESULT | LINE_ID | PLAY | SPEECH_NUM | ACT_SCENE_LINE | CHARACTER | LINE |
|--------+---------+---------------------------+------------+----------------+-----------------+--------------------------------------------------------|
| True | 75787 | Pericles | 178 | 1.0.21 | LODOVICO | This king unto him took a fere, |
| True | 43494 | King John | 1 | 1.1.1 | KING JOHN | Now, say, Chatillon, what would France with us? |
| True | 49031 | King Lear | 1 | 1.1.1 | KENT | I thought the king had more affected the Duke of |
| True | 78407 | Richard II | 1 | 1.1.1 | KING RICHARD II | Old John of Gaunt, time-honour'd Lancaster, |
| False | 67000 | A Midsummer Night's Dream | 1 | 1.1.1 | THESEUS | Now, fair Hippolyta, our nuptial hour |
| True | 4 | Henry IV Part 1 | 1 | 1.1.1 | KING HENRY IV | So shaken as we are, so wan with care, |
| False | 12664 | All's Well That Ends Well | 1 | 1.1.1 | COUNTESS | In delivering my son from me, I bury a second husband. |
| True | 9526 | Henry VI Part 3 | 1 | 1.1.1 | WARWICK | I wonder how the king escaped our hands. |
| False | 52797 | Love's Labour's Lost | 1 | 1.1.1 | FERDINAND | Let fame, that all hunt after in their lives, |
| True | 28487 | Cymbeline | 3 | 1.1.10 | First Gentleman | Is outward sorrow, though I think the king |
+--------+---------+---------------------------+------------+----------------+-----------------+--------------------------------------------------------+
필터링에 ILIKE 및 EXCLUDE 키워드를 사용할 수도 있습니다. 이러한 키워드에 대한 자세한 내용은 SELECT 섹션을 참조하십시오.
이 검색에서는 ILIKE 키워드를 사용하여 문자열 line
으로 끝나는 열에서만 검색합니다.
SELECT SEARCH(* ILIKE '%line', 'king') result, play, character, line
FROM lines
ORDER BY act_scene_line LIMIT 10;
+--------+---------------------------+-----------------+--------------------------------------------------------+
| RESULT | PLAY | CHARACTER | LINE |
|--------+---------------------------+-----------------+--------------------------------------------------------|
| True | Pericles | LODOVICO | This king unto him took a fere, |
| False | King John | KING JOHN | Now, say, Chatillon, what would France with us? |
| True | King Lear | KENT | I thought the king had more affected the Duke of |
| False | Richard II | KING RICHARD II | Old John of Gaunt, time-honour'd Lancaster, |
| False | A Midsummer Night's Dream | THESEUS | Now, fair Hippolyta, our nuptial hour |
| False | Henry IV Part 1 | KING HENRY IV | So shaken as we are, so wan with care, |
| False | All's Well That Ends Well | COUNTESS | In delivering my son from me, I bury a second husband. |
| True | Henry VI Part 3 | WARWICK | I wonder how the king escaped our hands. |
| False | Love's Labour's Lost | FERDINAND | Let fame, that all hunt after in their lives, |
| True | Cymbeline | First Gentleman | Is outward sorrow, though I think the king |
+--------+---------------------------+-----------------+--------------------------------------------------------+
이 검색에서는 EXCLUDE 키워드를 사용하므로 함수가 play
또는 line
열의 데이터를 검색하지 않습니다.
SELECT SEARCH(* EXCLUDE (play, line), 'king') result, play, character, line
FROM lines
ORDER BY act_scene_line LIMIT 10;
+--------+---------------------------+-----------------+--------------------------------------------------------+
| RESULT | PLAY | CHARACTER | LINE |
|--------+---------------------------+-----------------+--------------------------------------------------------|
| False | Pericles | LODOVICO | This king unto him took a fere, |
| True | King John | KING JOHN | Now, say, Chatillon, what would France with us? |
| False | King Lear | KENT | I thought the king had more affected the Duke of |
| True | Richard II | KING RICHARD II | Old John of Gaunt, time-honour'd Lancaster, |
| False | A Midsummer Night's Dream | THESEUS | Now, fair Hippolyta, our nuptial hour |
| True | Henry IV Part 1 | KING HENRY IV | So shaken as we are, so wan with care, |
| False | All's Well That Ends Well | COUNTESS | In delivering my son from me, I bury a second husband. |
| False | Henry VI Part 3 | WARWICK | I wonder how the king escaped our hands. |
| False | Love's Labour's Lost | FERDINAND | Let fame, that all hunt after in their lives, |
| False | Cymbeline | First Gentleman | Is outward sorrow, though I think the king |
+--------+---------------------------+-----------------+--------------------------------------------------------+
조인된 테이블의 적격 열에 대한 와일드카드 검색¶
이 예에서는 자동차 모델에 대한 정보가 포함된 2개의 작은 테이블을 사용합니다. 문자 열이 테이블 t1
에는 2개 있고, 테이블 t2
에는 3개 있습니다. 다음과 같이 테이블을 만들고 로드할 수 있습니다.
CREATE OR REPLACE TABLE t1 (col1 INT, col2 VARCHAR(20), col3 VARCHAR(20));
INSERT INTO t1 VALUES
(1,'Mini','Cooper'),
(2,'Mini','Cooper S'),
(3,'Mini','Countryman'),
(4,'Mini','Countryman S');
CREATE OR REPLACE TABLE t2 (col1 INT, col2 VARCHAR(20), col3 VARCHAR(20), col4 VARCHAR(20));
INSERT INTO t2 VALUES
(1,'Mini','Cooper', 'Convertible'),
(2,'Mini','Cooper S', 'Convertible'),
(3,'Mini','Countryman SE','ALL4'),
(4,'Mini','Countryman S','ALL4');
t1.*
및 t2.*
에 대한 검색을 고려할 때 다음 두 쿼리의 결과는 서로 다릅니다. t1
에서는 2개의 열만 검색에 적합하지만, t2
에서는 3개의 열이 적합합니다.
SELECT * FROM t1 JOIN t2 USING(col1)
WHERE SEARCH((t1.*),'s all4');
+------+------+--------------+------+--------------+-------------+
| COL1 | COL2 | COL3 | COL2 | COL3 | COL4 |
|------+------+--------------+------+--------------+-------------|
| 2 | Mini | Cooper S | Mini | Cooper S | Convertible |
| 4 | Mini | Countryman S | Mini | Countryman S | ALL4 |
+------+------+--------------+------+--------------+-------------+
SELECT * FROM t1 JOIN t2 USING(col1)
WHERE SEARCH((t2.*),'s all4');
+------+------+--------------+------+---------------+-------------+
| COL1 | COL2 | COL3 | COL2 | COL3 | COL4 |
|------+------+--------------+------+---------------+-------------|
| 2 | Mini | Cooper S | Mini | Cooper S | Convertible |
| 3 | Mini | Countryman | Mini | Countryman SE | ALL4 |
| 4 | Mini | Countryman S | Mini | Countryman S | ALL4 |
+------+------+--------------+------+---------------+-------------+
UNION 하위 쿼리 출력에 대한 와일드카드 검색¶
다음 예에서는 이전 예와 동일한 2개의 테이블을 사용합니다. 이 경우, 검색은 하위 쿼리의 결과로 반환되는 테이블인 t3
의 모든 적격 열에 적용됩니다. 하위 쿼리는 t1
및 t2
(5개 행)에서 처음 3개 열의 UNION을 계산합니다. 이 검색에서는 UNION 결과에서 일치하는 2개 행이 반환됩니다.
SELECT *
FROM (
SELECT col1, col2, col3 FROM t1
UNION
SELECT col1, col2, col3 FROM t2
) AS T3
WHERE SEARCH((T3.*),'s');
+------+------+--------------+
| COL1 | COL2 | COL3 |
|------+------+--------------|
| 2 | Mini | Cooper S |
| 4 | Mini | Countryman S |
+------+------+--------------+
여러 검색 문자열과 일치하는 행 찾기¶
다음 예에서는 동일한 쿼리에서 SEARCH를 두 번 사용하는 방법을 보여주는데, 두 검색 문자열 모두 TRUE를 반환해야 행이 결과에 적합하게 됩니다.
SELECT act_scene_line, character, line
FROM lines
WHERE SEARCH(line, 'Rosencrantz')
AND SEARCH(line, 'Guildenstern')
AND act_scene_line IS NOT NULL;
+----------------+------------------+-----------------------------------------------------------+
| ACT_SCENE_LINE | CHARACTER | LINE |
|----------------+------------------+-----------------------------------------------------------|
| 2.2.1 | KING CLAUDIUS | Welcome, dear Rosencrantz and Guildenstern! |
| 2.2.35 | KING CLAUDIUS | Thanks, Rosencrantz and gentle Guildenstern. |
| 2.2.36 | QUEEN GERTRUDE | Thanks, Guildenstern and gentle Rosencrantz: |
| 2.2.241 | HAMLET | Guildenstern? Ah, Rosencrantz! Good lads, how do ye both? |
| 4.6.27 | HORATIO | where I am. Rosencrantz and Guildenstern hold their |
| 5.2.60 | HORATIO | So Guildenstern and Rosencrantz go to't. |
| 5.2.389 | First Ambassador | That Rosencrantz and Guildenstern are dead: |
+----------------+------------------+-----------------------------------------------------------+
조인에서 VARIANT 및 VARCHAR 데이터 검색하기¶
다음 예에서는 두 테이블 car_rentals
와 car_sales
의 열에 검색을 적용했을 때 두 테이블의 조인을 보여줍니다. car_sales
테이블에는 VARIANT 데이터가 포함되어 있습니다. car_sales
테이블과 해당 데이터는 반정형 데이터 쿼리하기 아래에 설명되어 있습니다. 다음 SQL 문은 car_rentals
테이블을 생성하고 그 안에 데이터를 삽입합니다.
CREATE OR REPLACE TABLE car_rentals(
vehicle_make varchar(30),
dealership varchar(30),
salesperson varchar(30));
INSERT INTO car_rentals VALUES
('Toyota', 'Tindel Toyota', 'Greg Northrup'),
('Honda', 'Valley View Auto Sales', 'Frank Beasley'),
('Tesla', 'Valley View Auto Sales', 'Arturo Sandoval');
쿼리를 실행합니다.
SELECT SEARCH((r.vehicle_make, r.dealership, s.src:dealership), 'Toyota Tesla')
AS contains_toyota_tesla, r.vehicle_make, r.dealership,s.src:dealership
FROM car_rentals r JOIN car_sales s
ON r.SALESPERSON=s.src:salesperson.name;
+-----------------------+--------------+------------------------+--------------------------+
| CONTAINS_TOYOTA_TESLA | VEHICLE_MAKE | DEALERSHIP | S.SRC:DEALERSHIP |
|-----------------------+--------------+------------------------+--------------------------|
| True | Toyota | Tindel Toyota | "Tindel Toyota" |
| False | Honda | Valley View Auto Sales | "Valley View Auto Sales" |
+-----------------------+--------------+------------------------+--------------------------+
두 번째 예에서는 동일한 데이터에 대해 서로 다른 검색어가 사용됩니다.
SELECT SEARCH((r.vehicle_make, r.dealership, s.src:dealership), 'Toyota Honda')
AS contains_toyota_honda, r.vehicle_make, r.dealership, s.src:dealership
FROM car_rentals r JOIN car_sales s
ON r.SALESPERSON =s.src:salesperson.name;
+-----------------------+--------------+------------------------+--------------------------+
| CONTAINS_TOYOTA_HONDA | VEHICLE_MAKE | DEALERSHIP | S.SRC:DEALERSHIP |
|-----------------------+--------------+------------------------+--------------------------|
| True | Toyota | Tindel Toyota | "Tindel Toyota" |
| True | Honda | Valley View Auto Sales | "Valley View Auto Sales" |
+-----------------------+--------------+------------------------+--------------------------+
분석기를 사용하여 검색 동작 조정하기¶
다음 예에서는 기본 분석기가 아닌 분석기인 UNICODE_ANALYZER 또는 NO_OP_ANALYZER를 지정하여 SEARCH 함수의 동작을 조정하는 방법을 보여줍니다.
첫 번째 예에서는 NO_OP_ANALYZER를 사용하여 문자열 1.2.500
이 lines
테이블에 있는 모든 행에 대한 act_scene_line
열의 정확한 내용과 일치하는지 테스트합니다. 두 행이 검색에 적합합니다.
SELECT line_id, act_scene_line FROM lines
WHERE SEARCH(act_scene_line, '1.2.500', ANALYZER=>'NO_OP_ANALYZER');
+---------+----------------+
| LINE_ID | ACT_SCENE_LINE |
|---------+----------------|
| 91998 | 1.2.500 |
| 108464 | 1.2.500 |
+---------+----------------+
이 예에 나오는 함수의 인자인 NO_OP_ANALYZER를 제거하면 검색에서 많은 수의 행이 반환됩니다. 기본 분석기는 1, 2, 500을 서로 다른 토큰으로 처리하므로, 이 함수는 (순서나 조합에 관계없이) 1, 2 또는 500이 존재하는 모든 행에 대해 TRUE를 반환합니다.
두 번째 인자에 대해 접두사 1.2만 포함하도록 이 쿼리를 변경할 경우 기본 분석기는 TRUE를 반환하지만 UNICODE_ANALYZER와 NO_OP_ANALYZER는 모두 FALSE를 반환합니다. 기본 분석기는 이러한 값의 마침표를 구분 기호로 처리하지만 유니코드 분석기는 그렇지 않습니다.
다음 두 쿼리는 기본 분석기 대신 UNICODE_ANALYZER를 사용하는 또 다른 효과를 보여줍니다. UNICODE_ANALYZER를 사용하는 첫 번째 쿼리는 행을 하나만 반환합니다. 두 번째 인자에서 추가된 작은따옴표는 작은따옴표를 아포스트로피로 이스케이프하기 위한 것입니다. 작은따옴표로 묶인 문자열 상수 섹션을 참조하십시오.
SELECT DISTINCT(play)
FROM lines
WHERE SEARCH(play, 'love''s', ANALYZER=>'UNICODE_ANALYZER');
+----------------------+
| PLAY |
|----------------------|
| Love's Labour's Lost |
+----------------------+
기본 분석기가 아포스트로피 문자를 구분 기호로 처리하므로 기본 분석기를 사용하는 두 번째 쿼리는 4개의 행을 반환합니다. 문자 “s”를 토큰으로 포함하는 모든 문자열은 검색에 적합합니다. 이 예에서 함수는 “아포스트로피 s”('s
)를 포함하는 모든 문자열에 대해 TRUE를 반환합니다.
SELECT DISTINCT(play) FROM lines WHERE SEARCH(play, 'love''s');
+---------------------------+
| PLAY |
|---------------------------|
| All's Well That Ends Well |
| Love's Labour's Lost |
| A Midsummer Night's Dream |
| The Winter's Tale |
+---------------------------+
예상되는 오류 사례의 예¶
다음 예에서는 예상되는 구문 오류를 반환하는 쿼리를 보여줍니다.
다음 예시 코드는 5
가 search_string
인자에 대해 지원되는 데이터 타입이 아니므로 실패합니다.
SELECT SEARCH(line, 5) FROM lines;
001045 (22023): SQL compilation error:
argument needs to be a string: '1'
다음 예시 코드는 search_data
인자에 대해 지원되는 데이터 타입의 열이 지정되지 않았으므로 실패합니다.
SELECT SEARCH(line_id, 'dream') FROM lines;
001173 (22023): SQL compilation error: error line 1 at position 7: Expected non-empty set of columns supporting full-text search.
다음 예시 코드는 search_data
인자에 대해 지원되는 데이터 타입의 열이 지정되었으므로 성공합니다. 이 함수는 line_id
열이 지원되는 데이터 타입이 아니라 무시합니다.
SELECT SEARCH((line_id, play), 'dream') FROM lines
ORDER BY play LIMIT 5;
+----------------------------------+
| SEARCH((LINE_ID, PLAY), 'DREAM') |
|----------------------------------|
| True |
| True |
| False |
| False |
| False |
+----------------------------------+
다음 예시 코드는 첫 번째 인자에 대해 여러 문자열 리터럴이 괄호 없이 나열되어 있어 인자가 일치하지 않으므로 실패합니다.
SELECT SEARCH('docs@snowflake.com', 'careers@snowflake.com', '@');
001881 (42601): SQL compilation error: Expected 1 named argument(s), found 0
다음 예시 코드는 첫 번째 인자에 대해 여러 열 이름이 괄호 없이 나열되어 있어 인자가 너무 많으므로 실패합니다.
SELECT SEARCH(play,line,'king', ANALYZER=>'UNICODE_ANALYZER') FROM lines;
000939 (22023): SQL compilation error: error line 1 at position 7
too many arguments for function [SEARCH(LINES.PLAY, LINES.LINE, 'king', 'UNICODE_ANALYZER')] expected 3, got 4
다음 예시 코드는 열 이름이 검색 문자열 인자로 허용되지 않으므로 실패합니다.
SELECT SEARCH(line, character) FROM lines;
001015 (22023): SQL compilation error:
argument 2 to function SEARCH needs to be constant, found 'LINES.CHARACTER'
SEARCH에 대한 샘플 데이터¶
이 섹션의 일부 예제에서는 셰익스피어 희곡에 등장하는 텍스트가 포함된 테이블을 쿼리합니다. 각 텍스트 줄은 테이블의 단일 행에 저장됩니다. 다른 열에는 희곡 제목, 등장인물의 이름 등이 표시됩니다. lines
테이블의 구조는 다음과 같습니다.
DESCRIBE TABLE lines;
+----------------+---------------+--------+-------+-
| name | type | kind | null? |
|----------------+---------------+--------+-------+-
| LINE_ID | NUMBER(38,0) | COLUMN | Y |
| PLAY | VARCHAR(50) | COLUMN | Y |
| SPEECH_NUM | NUMBER(38,0) | COLUMN | Y |
| ACT_SCENE_LINE | VARCHAR(10) | COLUMN | Y |
| CHARACTER | VARCHAR(30) | COLUMN | Y |
| LINE | VARCHAR(2000) | COLUMN | Y |
+----------------+---------------+--------+-------+-
예를 들어, 이 테이블의 한 줄은 다음과 같습니다.
SELECT * FROM lines
WHERE line_id=34230;
+---------+--------+------------+----------------+-----------+--------------------------------------------+
| LINE_ID | PLAY | SPEECH_NUM | ACT_SCENE_LINE | CHARACTER | LINE |
|---------+--------+------------+----------------+-----------+--------------------------------------------|
| 34230 | Hamlet | 19 | 3.1.64 | HAMLET | To be, or not to be, that is the question: |
+---------+--------+------------+----------------+-----------+--------------------------------------------+
이 섹션의 예시 코드를 실행하려면 다음 명령을 실행하여 이 테이블을 만드십시오.
CREATE OR REPLACE TABLE lines(
line_id INT,
play VARCHAR(50),
speech_num INT,
act_scene_line VARCHAR(10),
character VARCHAR(30),
line VARCHAR(2000)
);
INSERT INTO lines VALUES
(4,'Henry IV Part 1',1,'1.1.1','KING HENRY IV','So shaken as we are, so wan with care,'),
(13,'Henry IV Part 1',1,'1.1.10','KING HENRY IV','Which, like the meteors of a troubled heaven,'),
(9526,'Henry VI Part 3',1,'1.1.1','WARWICK','I wonder how the king escaped our hands.'),
(12664,'All''s Well That Ends Well',1,'1.1.1','COUNTESS','In delivering my son from me, I bury a second husband.'),
(15742,'All''s Well That Ends Well',114,'5.3.378','KING','Your gentle hands lend us, and take our hearts.'),
(16448,'As You Like It',2,'2.3.6','ADAM','And wherefore are you gentle, strong and valiant?'),
(24055,'The Comedy of Errors',14,'5.1.41','AEMELIA','Be quiet, people. Wherefore throng you hither?'),
(28487,'Cymbeline',3,'1.1.10','First Gentleman','Is outward sorrow, though I think the king'),
(33522,'Hamlet',1,'2.2.1','KING CLAUDIUS','Welcome, dear Rosencrantz and Guildenstern!'),
(33556,'Hamlet',5,'2.2.35','KING CLAUDIUS','Thanks, Rosencrantz and gentle Guildenstern.'),
(33557,'Hamlet',6,'2.2.36','QUEEN GERTRUDE','Thanks, Guildenstern and gentle Rosencrantz:'),
(33776,'Hamlet',67,'2.2.241','HAMLET','Guildenstern? Ah, Rosencrantz! Good lads, how do ye both?'),
(34230,'Hamlet',19,'3.1.64','HAMLET','To be, or not to be, that is the question:'),
(35672,'Hamlet',7,'4.6.27','HORATIO','where I am. Rosencrantz and Guildenstern hold their'),
(36289,'Hamlet',14,'5.2.60','HORATIO','So Guildenstern and Rosencrantz go to''t.'),
(36640,'Hamlet',143,'5.2.389','First Ambassador','That Rosencrantz and Guildenstern are dead:'),
(43494,'King John',1,'1.1.1','KING JOHN','Now, say, Chatillon, what would France with us?'),
(43503,'King John',5,'1.1.10','CHATILLON','To this fair island and the territories,'),
(49031,'King Lear',1,'1.1.1','KENT','I thought the king had more affected the Duke of'),
(49040,'King Lear',4,'1.1.10','GLOUCESTER','so often blushed to acknowledge him, that now I am'),
(52797,'Love''s Labour''s Lost',1,'1.1.1','FERDINAND','Let fame, that all hunt after in their lives,'),
(55778,'Love''s Labour''s Lost',405,'5.2.971','ADRIANO DE ARMADO','Apollo. You that way: we this way.'),
(67000,'A Midsummer Night''s Dream',1,'1.1.1','THESEUS','Now, fair Hippolyta, our nuptial hour'),
(69296,'A Midsummer Night''s Dream',104,'5.1.428','PUCK','And Robin shall restore amends.'),
(75787,'Pericles',178,'1.0.21','LODOVICO','This king unto him took a fere,'),
(78407,'Richard II',1,'1.1.1','KING RICHARD II','Old John of Gaunt, time-honour''d Lancaster,'),
(91998,'The Tempest',108,'1.2.500','FERDINAND','Were I but where ''tis spoken.'),
(92454,'The Tempest',150,'2.1.343','ALONSO','Wherefore this ghastly looking?'),
(99330,'Troilus and Cressida',30,'1.1.102','AENEAS','How now, Prince Troilus! wherefore not afield?'),
(100109,'Troilus and Cressida',31,'2.1.53','ACHILLES','Why, how now, Ajax! wherefore do you thus? How now,'),
(108464,'The Winter''s Tale',106,'1.2.500','CAMILLO','As or by oath remove or counsel shake')
;