CONTAINS (Transact-SQL)
SQL Server で、単語または語句との完全一致検索やあいまい一致検索、特定の範囲内での検索、または重み付き検索を行います。 CONTAINS は、Transact-SQL SELECT ステートメントの WHERE 句で使用される関数です。文字ベースのデータ型を含むフルテキスト インデックス列で SQL Server のフルテキスト検索を実行します。
次に CONTAINS の検索対象を示します。
単語または語句。
単語または語句のプレフィックス。
別の単語の近くにある単語。
他の単語を語形変化して生成した単語。たとえば、drive という単語からは、drives、drove、driving、driven などの単語が生成されます。
別の単語のシノニムになっている単語 (類義語を使用)。たとえば、"金属" という単語には、"アルミニウム" や "スチール" などのシノニムがあります。
SQL Server でサポートされているフルテキスト検索の形式については、「フルテキスト検索でのクエリ」を参照してください。
適用対象: SQL Server (SQL Server 2008 から現在のバージョンまで) |
構文
CONTAINS (
{
column_name | ( column_list )
| *
| PROPERTY ( { column_name }, 'property_name' )
}
, '<contains_search_condition>'
[ , LANGUAGE language_term ]
)
<contains_search_condition> ::=
{
<simple_term>
| <prefix_term>
| <generation_term>
| <generic_proximity_term>
| <custom_proximity_term>
| <weighted_term>
}
|
{ ( <contains_search_condition> )
[ { <AND> | <AND NOT> | <OR> } ]
<contains_search_condition> [ ...n ]
}
<simple_term> ::=
{ word | "phrase" }
<prefix term> ::=
{ "word*" | "phrase*" }
<generation_term> ::=
FORMSOF ( { INFLECTIONAL | THESAURUS } , <simple_term> [ ,...n ] )
<generic_proximity_term> ::=
{ <simple_term> | <prefix_term> } { { { NEAR | ~ }
{ <simple_term> | <prefix_term> } } [ ...n ] }
<custom_proximity_term> ::=
NEAR (
{
{ <simple_term> | <prefix_term> } [ ,…n ]
|
( { <simple_term> | <prefix_term> } [ ,…n ] )
[, <maximum_distance> [, <match_order> ] ]
}
)
<maximum_distance> ::= { integer | MAX }
<match_order> ::= { TRUE | FALSE }
<weighted_term> ::=
ISABOUT
( {
{
<simple_term>
| <prefix_term>
| <generation_term>
| <proximity_term>
}
[ WEIGHT ( weight_value ) ]
} [ ,...n ]
)
<AND> ::=
{ AND | & }
<AND NOT> ::=
{ AND NOT | &! }
<OR> ::=
{ OR | | }
引数
column_name
FROM 句で指定したテーブルのフルテキスト インデックス付きの列の名前を指定します。 データ型が char、varchar、nchar、nvarchar、text、ntext、image、xml、varbinary、または varbinary(max) の列を指定できます。column_list
複数の列をコンマで区切って指定します。 column_list はかっこで囲む必要があります。 language_term を指定しない場合、column_list で指定するすべての列の言語は同じにする必要があります。*
検索条件の FROM 句で指定したテーブルのすべてのフルテキスト インデックス付きの列が検索対象になります。 CONTAINS 句内の列は、フルテキスト インデックスがある単一テーブルから取得する必要があります。 language_term を指定しない場合、テーブルのすべての列の言語は同じであることが必要です。PROPERTY ( column_name , 'property_name')
適用対象: SQL Server 2012 から SQL Server 2014
指定した検索条件を検索するドキュメント プロパティを指定します。
重要
行を返すクエリの場合、フルテキスト インデックスの検索プロパティ リストで property_name を指定し、フルテキスト インデックスに property_name のプロパティに固有のエントリを含める必要があります。詳細については、「検索プロパティ リストを使用したドキュメント プロパティの検索」を参照してください。
LANGUAGE language_term
クエリにおいて、単語区切り、語幹検索、類義語の拡張と置換、およびノイズ語 (ストップワード) の破棄を行うときに使用する言語を指定します。 このパラメーターはオプションです。1 つの列に複数の異なる言語のドキュメントがバイナリ ラージ オブジェクト (BLOB) として格納されている場合、インデックスの作成に使用される言語は、各ドキュメントのロケール識別子 (LCID) によって決まります。 そのような列に対してクエリを実行する場合は、LANGUAGE language_term を指定すると検索結果の一致率が高まります。
language_term には、言語の LCID に対応する文字列、整数、または 16 進数の値を指定できます。 language_term を指定した場合、その言語は検索条件のすべての要素に適用されます。 値を指定しなかった場合は、列のフルテキストの言語が使用されます。
language_term を文字列で指定する場合は、sys.syslanguages (Transact-SQL) 互換性ビューの alias 列の値と同じ値を指定します。 文字列の場合は、'language_term' のように引用符 (') で囲む必要があります。 language_term を整数で指定する場合は、その言語を表す実際の LCID を指定します。 language_term を 16 進数の値で指定する場合は、「0x」の後に LCID の 16 進数の値を指定します。 16 進数の値は、先頭の 0 を含め、8 桁以内で指定してください。
値を 2 バイト文字セット (DBCS) の形式で指定すると、SQL Server で Unicode に変換されます。
指定した言語が無効であるか、その言語に該当するリソースがインストールされていない場合は、エラーが返されます。 ニュートラル言語リソースを使用するには、language_term に「0x0」を指定してください。
<contains_search_condition>
column_name で検索するテキストと、その一致条件を指定します。<contains_search_condition> のデータ型は nvarchar です。 入力に他の文字データ型が使用された場合は、暗黙の変換が行われます。 次の例では、CONTAINS 述語において、varchar(30) として定義されている変数 @SearchWord が暗黙に変換されます。
USE AdventureWorks2012; GO DECLARE @SearchWord varchar(30) SET @SearchWord ='performance' SELECT Description FROM Production.ProductDescription WHERE CONTAINS(Description, @SearchWord);
変換では "パラメーターを見つけ出す" 動作が機能しないため、パフォーマンスの向上を目的とする場合には nvarchar を使用してください。 次の例では、@SearchWord を nvarchar(30) として宣言しています。
USE AdventureWorks2012; GO DECLARE @SearchWord nvarchar(30) SET @SearchWord = N'performance' SELECT Description FROM Production.ProductDescription WHERE CONTAINS(Description, @SearchWord);
最適化されていないプランが生成される場合には、OPTIMIZE FOR クエリ ヒントを使用することもできます。
word
スペースまたは句読点なしの文字列を指定します。phrase
単語の間をスペースで区切った 1 つ以上の単語を指定します。注意
一部のアジア言語など、言語の中には、語句を構成するときに単語の間にスペースを挿入しないものがあります。
<simple_term>
単語または語句に対する完全一致を指定します。 有効な単純語の例として、"blue berry"、blueberry、および "Microsoft SQL Server" などがあります。 語句は二重引用符 ("") で囲みます。 語句内の単語は、<contains_search_condition> の指定と同じ順序で、データベース列に含まれている必要があります。 単語または語句内の文字の検索では、大文字と小文字は区別されません。 フルテキスト インデックス化された列の a、and、the などのノイズ ワード (ストップワード) は、フルテキスト インデックスには格納されません。 1 つの単語の検索にノイズ ワードを使用した場合、SQL Server ではクエリにノイズ ワードだけが指定されていることを示すエラーが返されます。 SQL Server では、SQL Server の各インスタンスのディレクトリ \Mssql\Binn\FTERef にノイズ ワードの標準リストがあります。句読点は無視されます。 したがって、CONTAINS(testing, "computer failure") は、"Where is my computer? Failure to find it would be expensive." がある行に一致します。単語区切りの動作の詳細については、「検索用のワード ブレーカーとステミング機能の構成と管理」を参照してください。
<prefix_term>
指定のテキストで始まる単語または語句の照合を指定します。 プレフィックス語句を二重引用符 ("") で囲み、後ろの二重引用符の前にアスタリスク (*) を挿入すると、アスタリスクの前に指定された文字列で始まるすべてのテキストが照合されます。 句は、CONTAINS (column, '"text*"') のように指定してください。 アスタリスクは、一致する文字がないか、1 つまたはそれ以上の文字に一致します。その単語または語句を語根とする文字も対象になります。 テキストとアスタリスクが二重引用符で区切られていないと、述語が読み取る内容は CONTAINS (column, 'text*') となり、フルテキスト検索でアスタリスクが文字と見なされ、text* への完全一致が検索されます。 単語区切りでは通常このような文字は無視されるため、アスタリスク (*) 文字が付いた文字はフルテキスト エンジンによって検索されません。<prefix_term> が語句のときは、語句に含まれるそれぞれの単語が独立したプレフィックスと見なされます。 したがって、"local wine *" というプレフィックスを指定しているクエリでは、"local winery"、"locally wined and dined"などの行が一致します。
<generation_term>
指定されている原形の語または語句が、検索対象である元の単語の変形を含んでいる場合に、これらの単語も照合の対象であることを指定します。INFLECTIONAL
言語依存の語幹検索が、指定した単純語に対して使用されます。 語幹検索の動作は、特定の各言語の語幹ルールに基づいて定義されます。 ニュートラル言語には、関連する語幹検索がありません。 クエリの対象となっている列の列言語は、必要な語幹検索を参照する場合に使用されます。 language_term が指定されると、その言語に対応する語幹検索が使用されます。<generation_term> 内に指定された <simple_term> は、名詞と動詞のどちらにも一致しません。
THESAURUS
列のフルテキスト言語に対応する類義語、またはクエリで指定された言語が使用されます。 <simple_term> の最も長いパターンが類義語と照合され、追加の用語が生成されて、元のパターンを拡張するか置き換えます。 <simple_term> の全体または一部に対して一致が見られない場合、一致しない部分が simple_term として処理されます。 フルテキスト検索の類義語の詳細については、「フルテキスト検索に使用する類義語辞典ファイルの構成と管理」を参照してください。<generic_proximity_term>
検索対象のドキュメントに含まれている必要がある単語または語句の照合を指定します。重要
この機能は、将来のバージョンの Microsoft SQL Server では削除される予定です。新しい開発作業では、この機能の使用を避け、現在この機能を使用しているアプリケーションは修正するようにしてください。<custom_proximity_term> を使用することをお勧めします。
NEAR | ~
一致が返されるためには、NEAR (~) 演算子の両側の単語または語句がドキュメントに含まれている必要があります。 2 つの検索語句を指定する必要があります。 検索語句には、二重引用符で区切られた 1 つの単語または語句を指定できます ("phrase")。a NEAR b NEAR c または a ~ b ~ c のように、複数の近接語句をつないで指定できます。 一致が返されるためには、指定したすべての近接語句がドキュメントに含まれている必要があります。
たとえば、CONTAINS(column_name, 'fox NEAR chicken') と CONTAINSTABLE(table_name, column_name, 'fox ~ chicken') では、どちらの場合も、指定した列について "fox" と "chicken" の両方を含むドキュメントが返されますが、 CONTAINSTABLE ではさらに、"fox" と "chicken" の近接度に基づく各ドキュメントのランクも返されます。 たとえば、"The fox ate the chicken" という文が含まれているドキュメントのランクは高くなります。これは、他のドキュメントよりも語句が近接しているためです。
汎用近接語句の詳細については、「NEAR による他の単語の近くにある単語の検索」を参照してください。
<custom_proximity_term>
適用対象: SQL Server 2012 から SQL Server 2014
単語または語句の照合と、必要に応じて検索語句間の許容最大距離を指定します。 また、検索語句を指定したとおりの順序で検索するように指定することもできます (<match_order>)。
検索語句には、二重引用符で区切られた 1 つの単語または語句を指定できます ("phrase")。 一致が返されるためには、指定したすべての語句がドキュメントに含まれている必要があります。 2 つ以上の検索語句を指定する必要があります。 検索語句の最大数は 64 です。
既定では、カスタム近接語句の場合、語句の間の距離やその順序に関係なく、指定した語句が含まれているすべての行が返されます。 たとえば、次のクエリと一致するには、term1 と "term3 term4" が任意の場所に任意の順序でドキュメントに含まれているだけで十分です。
CONTAINS(column_name, 'NEAR(term1,"term3 term4")')
省略可能なパラメーターは次のとおりです。
<maximum_distance>
文字列と一致すると見なされるための、その文字列の先頭と末尾にある検索語句間の許容最大距離を指定します。integer
0 ~ 4294967295 の正の整数を指定します。 この値により、指定した他の検索用語を除く最初と最後の検索語句間にある非検索語句の数を制御します。たとえば、次のクエリでは、最大距離が 5 語以内で "AA" と "BB" を任意の順序で検索します。
CONTAINS(column_name, 'NEAR((AA,BB),5)')
文字列 "AA one two three four five BB" と一致します。 次の例のクエリでは、最大距離が 5 語以内で "AA"、"BB"、および "CC" の 3 つの検索語句を指定しています。
CONTAINS(column_name, 'NEAR((AA,BB,CC),5)')
このクエリでは、総距離が 5 語の次の文字列と一致します。
BB one two CC three four five AA
間に含まれている検索語句の "CC" はカウントされないことに注意してください。
MAX
距離に関係なく、指定した語句が含まれているすべての行を返します。 これは既定値です。
<match_order>
検索クエリによって返されるためには、語句が指定した順序で含まれている必要があるかどうかを指定します。 <match_order> を指定するには、<maximum_distance> も指定する必要があります。<match_order> には、次のいずれかの値を指定します。
TRUE
語句を指定した順序が適用されます。 たとえば、NEAR(A,B) は、A … B とだけ一致します。FALSE
指定した順序を無視します。 たとえば、NEAR(A,B) は、A … B と B … A の両方と一致します。これは既定値です。
たとえば、次の近接語句では、距離に関係なく、"Monday"、"Tuesday"、および "Wednesday" という単語を指定した順序で検索します。
CONTAINS(column_name, 'NEAR ((Monday, Tuesday, Wednesday), MAX, TRUE)')
カスタム近接語句の使用方法の詳細については、「NEAR による他の単語の近くにある単語の検索」を参照してください。
<weighted_term>
クエリによって取得された一致する行と、単語または語句のリストが照合されます。このリストの単語や語句のそれぞれには、オプションで重み付け値が指定されます。ISABOUT
<weighted_term> キーワードを指定します。WEIGHT(weight_value)
0.0 ~ 1.0 の間で重み値を指定します。 <weighted_term> 内の各構成要素には、weight_value を指定できます。 weight_value を指定すると、クエリのさまざまな部分がランク値に与える影響を変更することができます。このランク値とは、クエリに一致する各行に割り当てられる値です。 WEIGHT は CONTAINS クエリの結果に影響しませんが、WEIGHT は CONTAINSTABLE クエリ内のランクに影響します。注意
小数点区切り文字は、オペレーティング システムのロケールにかかわらず常にピリオドです。
{ AND | & } | { AND NOT | &! } | { OR | | }
2 つの contains 検索条件の間の論理演算を指定します。{ AND | & }
一致条件として、2 つの contains 検索条件を満たすことを指定します。 アンパサンド記号 (&) は、AND キーワードの代わりに使用して、AND 演算子を表すことができます。{ AND NOT | &! }
2 番目の検索条件が存在しないことを、一致条件として指定します。 アンパサンドとその次の感嘆符 (&!) は、AND NOT キーワードの代わりに使用して、AND NOT 演算子を表すことができます。{ OR | | }
一致条件として、2 つの contains 検索条件のいずれかを満たすことを指定します。 垂直バー記号 (|) は、OR キーワードの代わりに使用して、OR 演算子を表すことができます。<contains_search_condition> 内にかっこで囲まれたグループが含まれる場合は、かっこで囲まれたグループが最初に評価されます。 かっこで囲まれたグループを評価した後は、contains 検索条件で使用される論理演算子に対して次の規則が適用されます。
NOT は AND より先に適用されます。
NOT は AND NOT のように、AND の後にだけ指定できます。 OR NOT 演算子は使用できません。 NOT は最初の条件の前に指定できません。 たとえば、CONTAINS (mycolumn, 'NOT "phrase_to_search_for" ' ) は無効になります。
AND は OR より先に適用されます。
同じタイプの論理演算子 (AND、OR) は結合されるので、任意の順番で適用できます。
- n
複数の CONTAINS 検索条件と、条件内の複数の語を指定できることを示すプレースホルダーです。
全般的な解説
フルテキストの述語と関数の対象は、FROM 述語で示される 1 つのテーブルです。 複数のテーブルを検索するには、FROM 句で結合テーブルを使用して、複数のテーブルが組み合わされた結果セットを検索します。
データベースの互換性レベルが 100 に設定されている場合、OUTPUT 句でフルテキスト述語を使用することはできません。
リモート サーバーのクエリ
CONTAINS または FREETEXT 述語に 4 つの要素で構成される名前を使用して、リンク サーバー上の対象のテーブルのフルテキスト インデックス列にクエリを実行できます。 フルテキスト クエリを受け取るようリモート サーバーを準備するには、リモート サーバー上の検索対象のテーブルおよび列にフルテキスト インデックスを作成し、リモート サーバーをリンク サーバーとして追加します。
LIKE とフルテキスト検索の比較
フルテキスト検索とは異なり、LIKE Transact-SQL 述語は文字パターンにのみ有効です。 また、フォーマットされたバイナリ データのクエリには LIKE 述語を使用できません。 さらに、構造化されていない大量のテキスト データに対して LIKE クエリを実行すると、同じデータに対して同等のフルテキスト検索を実行する場合に比べてはるかに時間がかかります。 数百万行のテキスト データに対して LIKE クエリを実行すると、結果が得られるまでに数分かかる場合があります。一方、同じデータに対してフルテキスト クエリを実行すると、返される行数とサイズにもよりますが、数秒以内で結果を取得できます。 もう 1 つの注意事項は、LIKE ではテーブル全体の単純なパターンのスキャンしか実行されないことです。 これに対し、フルテキスト クエリでは、言語が識別され、インデックスの作成時やクエリの実行時に、ストップワードのフィルター処理、類義語辞典と変化形の拡張の作成など、特定の変換が適用されます。 これらの変換により、フルテキスト クエリの再呼び出しの精度および結果の最終的なランク付けを向上させることができます。
複数列のクエリ (フルテキスト検索)
検索する列のリストを指定することで、複数の列に対してクエリを実行できます。 クエリを実行する列は同じテーブルに含まれている必要があります。
たとえば、次の CONTAINS クエリでは、AdventureWorks2012 サンプル データベースの Production.Product テーブルの Name 列と Color 列内で、Red という語句を検索します。
Use AdventureWorks2012;
GO
SELECT Name, Color
FROM Production.Product
WHERE CONTAINS((Name, Color), 'Red');
使用例
A. CONTAINS を <simple_term> と共に使用する
次の例では、"Mountain" という単語を含み、価格が $80.99 であるすべての製品を検索します。
USE AdventureWorks2012;
GO
SELECT Name, ListPrice
FROM Production.Product
WHERE ListPrice = 80.99
AND CONTAINS(Name, 'Mountain');
GO
B. CONTAINS と語句を <simple_term> と共に使用する
次の例では、"Mountain" または "Road" のいずれかの語句が含まれている、すべての製品を返します。
USE AdventureWorks2012;
GO
SELECT Name
FROM Production.Product
WHERE CONTAINS(Name, ' Mountain OR Road ')
GO
C. CONTAINS を <prefix_term> と共に使用する
次の例では、Name 列の中で、chain というプレフィックスで始まる 1 つ以上の単語が含まれている、すべての製品名を返します。
USE AdventureWorks2012;
GO
SELECT Name
FROM Production.Product
WHERE CONTAINS(Name, ' "Chain*" ');
GO
D. CONTAINS および OR を <prefix_term> と共に使用する
次の例では、"chain" または "full" のいずれかのプレフィックスを持つ文字列が含まれている、すべてのカテゴリ説明を返します。
USE AdventureWorks2012;
GO
SELECT Name
FROM Production.Product
WHERE CONTAINS(Name, '"chain*" OR "full*"');
GO
E. CONTAINS を <proximity_term> と共に使用する
適用対象: SQL Server 2012 から SQL Server 2014 |
次の例では、Production.ProductReview テーブルを対象として、10 語以内の距離で "bike" と "control" という単語を含むすべてのコメントを、指定した順序 (つまり、"bike"、"control" の順) で検索します。
USE AdventureWorks2012;
GO
SELECT Comments
FROM Production.ProductReview
WHERE CONTAINS(Comments , 'NEAR((bike,control), 10, TRUE)');
GO
F. CONTAINS を <generation_term> と共に使用する
次の例では、ride を原型とする "riding"、"ridden" などの単語が含まれている、すべての製品を検索します。
USE AdventureWorks2012;
GO
SELECT Description
FROM Production.ProductDescription
WHERE CONTAINS(Description, ' FORMSOF (INFLECTIONAL, ride) ');
GO
G. CONTAINS を <weighted_term> と共に使用する
次の例では、performance、comfortable、または smooth という単語を含むすべての製品名を検索します。各単語にはそれぞれ異なる重み付けが割り当てられています。
USE AdventureWorks2012;
GO
SELECT Description
FROM Production.ProductDescription
WHERE CONTAINS(Description, 'ISABOUT (performance weight (.8),
comfortable weight (.4), smooth weight (.2) )' );
GO
H. CONTAINS を変数と共に使用する
次の例では、特定の検索語ではなく変数を使用します。
USE AdventureWorks2012;
GO
DECLARE @SearchWord nvarchar(30)
SET @SearchWord = N'Performance'
SELECT Description
FROM Production.ProductDescription
WHERE CONTAINS(Description, @SearchWord);
GO
I. CONTAINS を論理演算子 (AND) と共に使用する
次の例では、 AdventureWorks2012 データベースの ProductDescription テーブルを使用します。 このクエリでは、CONTAINS 述語を使用して、説明 ID が 5 以外で、説明に Aluminum と spindle という両方の単語が含まれている説明を検索します。 検索条件では、AND ブール演算子を使用します。
USE AdventureWorks2012;
GO
SELECT Description
FROM Production.ProductDescription
WHERE ProductDescriptionID <> 5 AND
CONTAINS(Description, 'Aluminum AND spindle');
GO
J. CONTAINS を使用して行の挿入を確認する
次の例では、SELECT サブクエリ内で CONTAINS を使用します。 AdventureWorks2012 データベースを使用して、特定の自転車の ProductReview テーブルですべてのコメントのコメント値を取得します。 検索条件では、AND ブール演算子を使用します。
USE AdventureWorks2012;
GO
INSERT INTO Production.ProductReview
(ProductID, ReviewerName, EmailAddress, Rating, Comments)
VALUES
(780, 'John Smith', 'john@fourthcoffee.com', 5,
'The Mountain-200 Silver from AdventureWorks2008 Cycles meets and exceeds expectations. I enjoyed the smooth ride down the roads of Redmond');
-- Given the full-text catalog for these tables is Adv_ft_ctlg,
-- with change_tracking on so that the full-text indexes are updated automatically.
WAITFOR DELAY '00:00:30';
-- Wait 30 seconds to make sure that the full-text index gets updated.
SELECT r.Comments, p.Name
FROM Production.ProductReview r
JOIN Production.Product p
ON
r.ProductID = p.ProductID
AND r.ProductID = (SELECT ProductID
FROM Production.ProductReview
WHERE CONTAINS (Comments,
' AdventureWorks2008 AND
Redmond AND
"Mountain-200 Silver" '));
GO
K. ドキュメント プロパティに対してクエリを実行する
適用対象: SQL Server 2012 から SQL Server 2014 |
次のクエリでは、Production.Document テーブルの Document 列内で、インデックス化されたプロパティ Title を検索します。 このクエリは、Maintenance または Repair という文字列が Title プロパティに含まれているドキュメントのみを返します。
注意
プロパティ検索で行が返されるためには、インデックスの作成中に列を解析するフィルターによって、指定されたプロパティが抽出される必要があります。また、指定されたテーブルのフルテキスト インデックスが、プロパティを含めるように構成されている必要があります。詳細については、「検索プロパティ リストを使用したドキュメント プロパティの検索」を参照してください。
Use AdventureWorks2012;
GO
SELECT Document FROM Production.Document
WHERE CONTAINS(PROPERTY(Document,'Title'), 'Maintenance OR Repair');
GO
関連項目
タスク
フルテキスト検索クエリの作成 (Visual Database Tools)
参照
CREATE FULLTEXT CATALOG (Transact-SQL)
CREATE FULLTEXT INDEX (Transact-SQL)