文字列を含む行を持つテーブルの行を見つけたい
たとえば、「testing」という名前のテーブルに「atest」という名前の列に行があります-
test
a
cool
another
SQLを使用して、文字列「これはテストです」から単語を持つ行を選択したい
select * from testing where instr(atext, 'this is a test') >0;
しかし、これは行を選択していません。
の引数を逆にしますINSTR
。
WHERE INSTR('this is a test', atext)
これは次のような「逆」です。
select * from testing where 'this is a test' LIKE CONCAT('%',atext,'%');
多くのレコードを持つテーブルでは遅くなる可能性があります。これは、指定された文字列で atext 列の値が見つかる行を返します。(たとえば、atext = 'is a t' は、指定された文字列で見つかるため、一致します)
または、正規表現を書くこともできます。
select * from testing where atext REGEXP '^(this|is|a|test)$';
これは、指定された単語を正確に含むすべての行に一致します。スクリプトまたはプログラミング言語では、スペースのみを | に置き換える必要があります。文字列の先頭に ^ を追加し、文字列の末尾に $ を追加し、式ではなく REGEXP を追加します。(「これはテストです」 -> ^this|is|a|test$ )
テーブルに多数のレコードがある場合、このクエリは遅くなる可能性があります。SQL エンジンは正規表現クエリでインデックスを使用しないためです。
したがって、テーブルに多くの行があり、4 000 000 語を超えない場合は、インデックス テーブルを作成することをお勧めします。例:
originalTable:
tid | atext (text)
1 | this is
2 | a word
3 | a this
4 | this word
5 | a is
....
indexTable:
wid | word (varchar)
1 | this
2 | is
3 | a
4 | word
switchTable:
tid | wid
1 | 1
1 | 2
2 | 3
2 | 4
3 | 1
3 | 3
...
インデックス、tid、wid、および word フィールドを設定する必要があります。
クエリは次のとおりです。
SELECT o.*
FROM originalTable as o
JOIN switchTable as s ON o.tid = s.tid
JOIN indexTable as i on i.wid=s.wid
WHERE i.word = 'this' or i.word='is' or i.word='a' or i.word='test'
originalTable に「たくさん」のレコードがある場合、このクエリは非常に高速になる可能性があります。これは、ここで SQL エンジンがインデックス付き検索を実行できるためです。ただし、元のテーブルに行を挿入するときは、他の 2 つのテーブルに挿入する必要があるため、もう少し作業が必要です。
3 つのクエリの実行間の結果は、データベース テーブルのサイズによって異なります。また、挿入または選択を最適化したい場合。(挿入/更新クエリと選択クエリの間のレート)
全文索引付き -
select * from anti_spam where match (atext) against ("this is a test" in boolean mode);