- 类别:
:doc:`/sql-reference/functions-string`(全文搜索)
SEARCH¶
Searches character data (text) in specified columns from one or more tables, including fields in VARIANT, OBJECT, and ARRAY columns. A text analyzer breaks the text into tokens, which are discrete units of text, such as words or numbers. A default analyzer is applied if you don't specify one.
有关使用此函数的更多信息,请参阅 使用全文搜索。
语法¶
SEARCH( <search_data>, '<search_string>'
[ , ANALYZER => '<analyzer_name>' ]
[ , SEARCH_MODE => { 'OR' | 'AND' | 'PHRASE' | 'EXACT' } ] )
必填实参¶
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 集合运算符从多个表中搜索列。要搜索联接或 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')
If parentheses aren't used to separate multiple items, commas are parsed as separators between function arguments.
另请参阅 预期错误案例的示例。
您可以通过指定列名、冒号或点以及用点分隔的子字段,在 VARIANT 数据中搜索字段。例如:
colname:fieldname.subfieldname。有关在此类列中指定字段的更多信息,请参阅 遍历半结构化数据。'search_string'一个 VARCHAR 字符串,包含一个或多个搜索词。此参数必须是字面量字符串;不支持列名。用一对单引号将整个字符串括起来。不用引号将个别搜索词或短语括起来。例如,请使用:
'blue red green'不要使用:
'blue' 'red' 'green'The list of terms can be disjunctive or conjunctive when
ORorANDis set for the SEARCH_MODE argument. However, when the'NO_OP_ANALYZER'is used, the query string is matched exactly as it is, with no tokenization and no disjunctive or conjunctive semantics.Searches aren't case sensitive, except when the
'NO_OP_ANALYZER'is used, so a search for the term'ONCE'against the string'Once upon a time'returns TRUE.当为 SEARCH_MODE 实参设置
OR或AND时,搜索词的顺序并不重要,只要它们在搜索数据中的存在即可。当为 SEARCH_MODE 实参设置PHRASE或EXACT时,搜索词的顺序必须与被搜索数据中的顺序完全一致。
可选实参¶
ANALYZER => 'analyzer_name'文本分析器的名称。名称必须放在单引号内。
The analyzer breaks the search terms (and the text from the column being searched) into tokens. The matching semantics (disjunctive, conjunctive, phrase, or exact) for tokens extracted from the search string and tokens extracted from the columns or fields being searched depends on the value of the SEARCH_MODE argument.
The analyzer tokenizes a string by breaking it where it finds certain delimiters. These delimiters aren't included in the resulting tokens, and empty tokens aren't extracted.
该参数可接受以下值:
'DEFAULT_ANALYZER'- Breaks text into tokens based on the following delimiters:字符
Unicode 代码
描述
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下划线(底线)
\nU+000A新行(换行符)
\rU+000D回车
\tU+0009水平制表符
'UNICODE_ANALYZER'- Tokenizes based on Unicode segmentation rules that treat spaces and certain punctuation characters as delimiters. These internal rules are designed for natural language searches in many different languages. For example, the default analyzer treats periods in IP addresses and apostrophes in contractions as delimiters, but the Unicode analyzer doesn't. See 使用分析器来调整搜索行为.有关 Unicode Text Segmentation 算法的更多信息,请参阅 https://unicode.org/reports/tr29/ (https://unicode.org/reports/tr29/)。
'NO_OP_ANALYZER'- Tokenizes neither the data nor the query string. A search term must exactly match the full text in a column or field, including case sensitivity; otherwise, the SEARCH function returns FALSE. Even if the query string looks like it contains multiple tokens --- for example,'sky blue'--- the column or field must equal the entire query string exactly. In this case, only'sky blue'is a match;'sky'and'blue'aren't matches.
有关不同分析器行为的更多信息,请参阅 如何将搜索词划分为词元。
SEARCH_MODE => { 'OR' | 'AND' | 'PHRASE' | 'EXACT' }The semantics used by the search. Set this argument to one of the following values:
'OR'- The function uses disjunctive semantics. There is a match if any of the tokens extracted from the columns or fields being searched match any of the tokens extracted from the search string. For example, if thesearch_stringvalue is'blue red green', the function returns TRUE for a row that containsblueORredORgreenin any of the columns or fields being searched.'AND'- The function uses conjunctive semantics. There is a match if the tokens extracted from at least one of the columns or fields being searched matches all of the tokens extracted from the search string. The matching tokens must all be in one column or field; they can't be spread across multiple columns or fields. For example, if thesearch_stringvalue is'blue red green', the function returns TRUE for a row that containsblueANDredANDgreenin at least one of the columns or fields being searched.'PHRASE'– 该函数使用的是短语匹配语义。如果从 至少一个 被搜索列或字段中提取的词元与从搜索字符串中提取的 所有 词元相匹配(包括词元的顺序和相邻关系),则认为匹配成功。匹配语义与合取语义相同,但以下差异除外:
词元的顺序必须完全匹配。例如,如果
search_string值为'blue,red,green',则对于red,green,blue,函数返回 FALSE。搜索数据中不得插入其他词元。例如,如果
search_string值为'blue,red,green',则对于blue,yellow,red,green,函数返回 FALSE。
'EXACT'– 该函数使用的是完全匹配语义。如果从 至少一个 被搜索列或字段中提取的词元与从搜索字符串(包括分隔符)中提取的 所有 词元相匹配,则认为匹配成功。匹配语义与短语搜索语义相同,但以下差异除外:
词元之间的分隔符字符串必须完全匹配。例如,如果
search_string值为'blue,red,green',则对于在至少一个被搜索的列或字段中包含blue,red,green的行,函数返回 TRUE。对于变体(例如blue|red|green或blue, red, green),函数返回 FALSE。当分隔符是
search_string值中的第一个或最后一个字符时,分隔符会被视为匹配字符。因此,第一个和最后一个分隔符左侧和右侧的分隔符也可能导致匹配。例如,如果search_string值为'[blue]',对于foo [blue] bar、[[blue]]`和 :code:`=[blue].,函数返回 TRUE,但不适用于(blue)或foo blue bar。
对于所有搜索模式,字符串的左右两侧必须由分隔符符号分隔。例如,如果
search_string值为'blue,red,green',则对于-blue,red,green;,函数返回 TRUE。对于darkblue,red,green或blue,red,greenish,函数将返回 FALSE。如果您使用
UNICODE_ANALYZER,则不支持完全匹配语义。您可以将DEFAULT_ANALYZER或NO_OP_ANALYZER与完全匹配语义结合使用,但通常此类搜索语义最适用于DEFAULT_ANALYZER。使用
DEFAULT_ANALYZER的完全匹配搜索在以下方面与等值搜索或使用NO_OP_ANALYZER的全文搜索有所不同:等值搜索会匹配列值与谓词中的值完全相同的行(包括字母大小写),且搜索字符串周围不允许有额外文本。
使用
NO_OP_ANALYZER的全文搜索与等值搜索类似,它区分大小写且不允许额外文本。使用
DEFAULT_ANALYZER的完全匹配语义会对列值进行划分词元处理。只要搜索字符串前后出现的额外词元由词元分隔符隔开,即允许存在此类词元。搜索不区分大小写。
默认:
'OR'
返回¶
返回 BOOLEAN:
如果根据 SEARCH_MODE 实参中指定的语义,
search_string词元与search_data词元相匹配,则值为 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(不拆分) |
|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
示例¶
The following examples show different ways to use the SEARCH function, starting with simple usage and progressing to more complex use cases:
要运行多个示例中的查询,请首先 为 SEARCH 函数创建示例数据。
匹配字面量¶
最简单的 SEARCH 函数的例子是在字符串字面量上对 TRUE 或 FALSE 的测试。第一个示例返回 TRUE,因为第一个和第二个实参的字面量匹配,前提是比较不区分大小写。
SELECT SEARCH('king','KING');
+-----------------------------+
| SEARCH('KING','KING') |
|-----------------------------|
| True |
+-----------------------------+
第二个示例返回 FALSE,因为在为第一个实参指定的字面量 5.1.33 中没有出现词元 32。
SELECT SEARCH('5.1.33','32');
+-----------------------------+
| SEARCH('5.1.33','32') |
|-----------------------------|
| False |
+-----------------------------+
匹配列引用¶
此示例使用表中的一列作为第一个实参。该函数返回 TRUE,因为搜索词之一 (king) 存在于 character 列中。术语列表是析取的,因为 SEARCH_MODE 实参的默认值为 'OR'。(有关此处及后续示例中使用的表的信息,请参阅 Creating the sample data for SEARCH。)
SELECT SEARCH(character, 'king queen'), character
FROM lines
WHERE line_id=4;
+---------------------------------+---------------+
| SEARCH(CHARACTER, 'KING QUEEN') | CHARACTER |
|---------------------------------+---------------|
| True | KING HENRY IV |
+---------------------------------+---------------+
下面的示例与前面的示例类似,但搜索语义是合取的,因为 SEARCH_MODE 实参设置为 'AND'。该函数返回 FALSE,因为搜索词之一 (king) 仅存在于 character 列中。术语 queen 未出现在搜索数据中。
SELECT SEARCH(character, 'king queen', SEARCH_MODE => 'AND'), character
FROM lines
WHERE line_id=4;
+-------------------------------------------------------+---------------+
| SEARCH(CHARACTER, 'KING QUEEN', SEARCH_MODE => 'AND') | CHARACTER |
|-------------------------------------------------------+---------------|
| False | 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 表有四个列,具有搜索功能支持的数据类型。结果由在四个搜索列中的一个或多个列中出现“king”的行组成。对于其中一列 (act_scene_line),该函数未找到匹配项,但其他三列都有匹配项。SEARCH_MODE 实参默认为 'OR'。
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 结尾的列中进行搜索。因此,该函数在 line 和 act_scene_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 表)中的所有符合条件的列进行操作。当 king 出现在四个搜索列中的一个或多个中时,搜索返回 TRUE。SEARCH_MODE 实参默认为 'OR'。
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 结尾的列中进行搜索。因此,该函数在 line 和 act_scene_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 |
+--------+---------------------------+-----------------+--------------------------------------------------------+
在联接的表中对符合条件的列进行通配符搜索¶
此示例使用了两个小表,其中包含有关汽车型号的信息。表 t1 有两个字符列,表 t2 有三个。您可以创建和加载这些表,如下所示:
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 中只有两列符合搜索条件,但 t2 中有三列符合条件。
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 子查询的输出执行通配符搜索¶
以下示例使用与前一个示例相同的两个表。在本例中,搜索应用于来自 t3``(它是子查询产生的表)的所有符合条件的列。子查询会计算 ``t1 和 ``t2``(五行)中前三列的 UNION。搜索返回了 UNION 结果中的两个匹配行。
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_MODE 实参来指定合取语义,即当两个搜索词同时出现在同一列中时,才能找到匹配项。要使用合取语义,请将 SEARCH_MODE 实参设置为 'AND'。
SELECT act_scene_line, character, line
FROM lines
WHERE SEARCH(line, 'Rosencrantz Guildenstern', SEARCH_MODE => 'AND')
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: |
+----------------+------------------+-----------------------------------------------------------+
当您使用合取语义时,同一列中的两个搜索词必须匹配。例如,以下查询不会返回任何结果,因为术语 KING 和 Rosencrantz 没有出现在搜索数据的任何行的同一列中。
SELECT act_scene_line, character, line
FROM lines
WHERE SEARCH(line, 'KING Rosencrantz', SEARCH_MODE => 'AND')
AND act_scene_line IS NOT NULL;
+----------------+-----------+------+
| ACT_SCENE_LINE | CHARACTER | LINE |
|----------------+-----------+------|
+----------------+-----------+------+
类似的查询使用析取的语义(默认),通过将 SEARCH_MODE 实参设置为 'OR',在搜索数据中查找匹配项。
SELECT act_scene_line, character, line
FROM lines
WHERE SEARCH(line, 'KING Rosencrantz', SEARCH_MODE => 'OR')
AND act_scene_line IS NOT NULL;
+----------------+------------------+-----------------------------------------------------------+
| ACT_SCENE_LINE | CHARACTER | LINE |
|----------------+------------------+-----------------------------------------------------------|
| 1.1.1 | WARWICK | I wonder how the king escaped our hands. |
| 1.1.10 | First Gentleman | Is outward sorrow, though I think the king |
| 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: |
| 1.1.1 | KENT | I thought the king had more affected the Duke of |
| 1.0.21 | LODOVICO | This king unto him took a fere, |
+----------------+------------------+-----------------------------------------------------------+
使用短语匹配和完全匹配语义查找行¶
对于类似但略有不同的用例,您可以使用短语匹配和完全匹配语义
当单词和单词的顺序必须完全匹配,但单词之间的分隔符和空格可以存在差异时,使用短语匹配语义。要使用短语匹配语义,请将 SEARCH_MODE 实参设置为
'PHRASE'。当单词、单词的顺序、单词之间的分隔符以及单词之间的空格必须完全匹配时,使用完全匹配语义。要使用完全匹配语义,请将 SEARCH_MODE 实参设置为
'EXACT'。
以下示例使用短语匹配语义,在较长的文本字符串中查找文本的完全匹配项,但搜索文本中的分隔符不同,并且单词之间存在额外空格:
SELECT act_scene_line, character, line
FROM lines
WHERE SEARCH(line, 'Why - how now: Ajax!', SEARCH_MODE => 'PHRASE');
+----------------+-----------+-----------------------------------------------------+
| ACT_SCENE_LINE | CHARACTER | LINE |
|----------------+-----------+-----------------------------------------------------|
| 2.1.53 | ACHILLES | Why, how now, Ajax! wherefore do you thus? How now, |
+----------------+-----------+-----------------------------------------------------+
下面的示例与前一个示例相同,不同之处在于它使用完全匹配语义,在较长的文本字符串中查找文本的完全匹配项:
SELECT act_scene_line, character, line
FROM lines
WHERE SEARCH(line, 'Why, how now, Ajax!', SEARCH_MODE => 'EXACT');
+----------------+-----------+-----------------------------------------------------+
| ACT_SCENE_LINE | CHARACTER | LINE |
|----------------+-----------+-----------------------------------------------------|
| 2.1.53 | ACHILLES | Why, how now, Ajax! wherefore do you thus? How now, |
+----------------+-----------+-----------------------------------------------------+
短语匹配和完全匹配语义的常见用例包括查找电子邮件地址、URLs 和电话号码。在接下来的示例中,请创建一个包含一行示例数据的表:
CREATE OR REPLACE TABLE phrase_exact_search_samples (
email VARCHAR,
url VARCHAR,
phone VARCHAR);
INSERT INTO phrase_exact_search_samples VALUES (
'john.robert.doe@mycompany.com',
'http://mycompany.com/product/id-12345.67',
'800-555-0100');
The following example runs a query that uses conjunctive semantics to search the email data by setting the SEARCH_MODE
argument to 'AND' in the first search, phrase-match semantics in the second search, and exact-match semantics
in the third search:
SELECT email AS search_data,
SEARCH(email, 'doe.john.robert@mycompany.com', SEARCH_MODE => 'AND') AS conjunctive_search,
SEARCH(email, 'doe.john.robert@mycompany.com', SEARCH_MODE => 'PHRASE') AS phrase_search,
SEARCH(email, 'doe.john.robert@mycompany.com', SEARCH_MODE => 'EXACT') AS exact_search
FROM phrase_exact_search_samples;
输出结果显示如下:
AND搜索返回 TRUE,即使搜索字符串和搜索数据中的术语john、robert和doe顺序不同。PHRASE和EXACT搜索返回 FALSE,因为搜索词的顺序与搜索字符串不匹配。
+-------------------------------+--------------------+---------------+--------------+
| SEARCH_DATA | CONJUNCTIVE_SEARCH | PHRASE_SEARCH | EXACT_SEARCH |
|-------------------------------+--------------------+---------------+--------------|
| john.robert.doe@mycompany.com | True | False | False |
+-------------------------------+--------------------+---------------+--------------+
The following example runs a query that uses conjunctive semantics to search the email data by setting
the SEARCH_MODE argument to 'AND' in the first search, phrase-match semantics in the second search, and exact-match
semantics in the third search:
SELECT email AS search_data,
SEARCH(email, 'john.doe@mycompany.com', SEARCH_MODE => 'AND') AS conjunctive_search,
SEARCH(email, 'john.doe@mycompany.com', SEARCH_MODE => 'PHRASE') AS phrase_search,
SEARCH(email, 'john.doe@mycompany.com', SEARCH_MODE => 'EXACT') AS exact_search
FROM phrase_exact_search_samples;
输出结果显示如下:
AND搜索返回 TRUE,即使搜索数据中穿插了额外词元robert。PHRASE与EXACT搜索均返回 FALSE,因为当搜索数据中穿插额外词元时,这些搜索语义无法找到匹配项。
+-------------------------------+--------------------+---------------+--------------+
| SEARCH_DATA | CONJUNCTIVE_SEARCH | PHRASE_SEARCH | EXACT_SEARCH |
|-------------------------------+--------------------+---------------+--------------|
| john.robert.doe@mycompany.com | True | False | False |
+-------------------------------+--------------------+---------------+--------------+
以下示例通过运行查询演示:首次搜索使用短语匹配语义检索电子邮件数据,第二次搜索则使用完全匹配语义:
SELECT email AS search_data,
SEARCH(email, 'john-robert-doe@mycompany.com', SEARCH_MODE => 'PHRASE') AS phrase_search,
SEARCH(email, 'john-robert-doe@mycompany.com', SEARCH_MODE => 'EXACT') AS exact_search
FROM phrase_exact_search_samples;
输出显示,PHRASE 搜索返回 TRUE,即使搜索字符串中电子邮件地址的分隔符是连字符,而不是 john、robert 和 doe 之间的句点。EXACT 搜索返回 FALSE,因为在完全匹配语义下,搜索字符串中的分隔符必须与搜索数据完全一致。
+-------------------------------+---------------+--------------+
| SEARCH_DATA | PHRASE_SEARCH | EXACT_SEARCH |
|-------------------------------+---------------+--------------|
| john.robert.doe@mycompany.com | True | False |
+-------------------------------+---------------+--------------+
以下示例通过运行查询演示:首次搜索使用短语匹配语义检索 URL 数据,第二次搜索则使用完全匹配语义:
SELECT url AS search_data,
SEARCH(url, 'http://mycompany.com/product/id-12345_67', SEARCH_MODE => 'PHRASE') AS phrase_search,
SEARCH(url, 'http://mycompany.com/product/id-12345_67', SEARCH_MODE => 'EXACT') AS exact_search
FROM phrase_exact_search_samples;
输出显示,PHRASE 搜索返回 TRUE,即使搜索字符串中 URL 的分隔符是下划线,而不是产品 ID 中的句点。EXACT 搜索返回 FALSE:
+------------------------------------------+---------------+--------------+
| SEARCH_DATA | PHRASE_SEARCH | EXACT_SEARCH |
|------------------------------------------+---------------+--------------|
| http://mycompany.com/product/id-12345.67 | True | False |
+------------------------------------------+---------------+--------------+
以下示例通过运行查询演示:首次搜索使用短语匹配语义检索电话号码数据,第二次搜索则使用完全匹配语义:
SELECT phone AS search_data,
SEARCH(phone, '800.555.0100', SEARCH_MODE => 'PHRASE') AS phrase_search,
SEARCH(phone, '800.555.0100', SEARCH_MODE => 'EXACT') AS exact_search
FROM phrase_exact_search_samples;
输出显示,PHRASE 搜索返回 TRUE,即使搜索字符串中的电话号码分隔符是句点,而不是连字符。EXACT 搜索返回 FALSE:
+--------------+---------------+--------------+
| SEARCH_DATA | PHRASE_SEARCH | EXACT_SEARCH |
|--------------+---------------+--------------|
| 800-555-0100 | True | False |
+--------------+---------------+--------------+
以下示例在 WHERE 子句中使用 SEARCH 函数来查询 phrase_exact_search_samples 表。首先,向表中插入另一行数据:
INSERT INTO phrase_exact_search_samples VALUES (
'jane.smith@mycompany.com',
'http://mycompany.com/product/id-89012.34',
'800-555-0199');
以下示例在表数据中搜索电话号码 800-555-0100 的完全匹配项:
SELECT *
FROM phrase_exact_search_samples
WHERE SEARCH(phone, '800-555-0100', SEARCH_MODE => 'EXACT');
+-------------------------------+------------------------------------------+--------------+
| EMAIL | URL | PHONE |
|-------------------------------+------------------------------------------+--------------|
| john.robert.doe@mycompany.com | http://mycompany.com/product/id-12345.67 | 800-555-0100 |
+-------------------------------+------------------------------------------+--------------+
以下示例与前一示例相同,但改用析取语义替代完全匹配语义,从而任何包含 800 或 555 的电话号码都会匹配:
SELECT *
FROM phrase_exact_search_samples
WHERE SEARCH(phone, '800-555-0100', SEARCH_MODE => 'OR');
+-------------------------------+------------------------------------------+--------------+
| EMAIL | URL | PHONE |
|-------------------------------+------------------------------------------+--------------|
| john.robert.doe@mycompany.com | http://mycompany.com/product/id-12345.67 | 800-555-0100 |
| jane.smith@mycompany.com | http://mycompany.com/product/id-89012.34 | 800-555-0199 |
+-------------------------------+------------------------------------------+--------------+
在联接中搜索 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" |
+-----------------------+--------------+------------------------+--------------------------+
使用分析器来调整搜索行为¶
The following examples show how to adjust the behavior of the SEARCH function by specifying a
non-default analyzer: 'UNICODE_ANALYZER' or 'NO_OP_ANALYZER'.
The first example uses the 'NO_OP_ANALYZER' to test whether the string 1.2.500 matches the exact contents
of the act_scene_line column for any row in the lines table. Two rows qualify for the search.
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 |
+---------+----------------+
If you remove 'NO_OP_ANALYZER' as an argument to the function for this example, the search returns a large
number of rows. The default analyzer treats 1, 2, and 500 as distinct tokens; therefore, the function
returns TRUE for all of the rows where 1, 2, or 500 exist in any order or combination.
If you change this query to include only the prefix 1.2 for the second argument, the default analyzer
returns TRUE, but the 'UNICODE_ANALYZER' and 'NO_OP_ANALYZER' both return FALSE. The default analyzer treats
periods in these values as delimiters, but the Unicode analyzer doesn't.
The following two queries show another effect of using the 'UNICODE_ANALYZER' instead of the default analyzer. The
first query, using the 'UNICODE_ANALYZER', returns only one row. The extra single quote in the second
argument is there to escape the single quote for the apostrophe. See 单引号字符串常量.
SELECT DISTINCT(play)
FROM lines
WHERE SEARCH(play, 'love''s', ANALYZER=>'UNICODE_ANALYZER');
+----------------------+
| PLAY |
|----------------------|
| Love's Labour's Lost |
+----------------------+
第二个查询使用默认分析器,返回四行,因为默认分析器将撇号字符视为分隔符。任何包含字母 "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'
Creating the sample data for 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')
;