テキストフィールドでキーワードを検索するSQLクエリを作成したいのですが、「完全一致」の場合のみ(たとえば、「rid」を検索する場合、「arid」とは一致しませんが、 「a rid」に一致します。
MySQLを使用しています。
幸いなことに、このアプリケーションではパフォーマンスは重要ではなく、データベースサイズと文字列サイズはどちらも快適に小さくなりますが、PHPを駆動するよりもSQLで実行することをお勧めします。
REGEXP
および[[:<:]]
および[[:>:]]
単語境界マーカー:
SELECT *
FROM table
WHERE keywords REGEXP '[[:<:]]rid[[:>:]]'
古典的なWordの境界を防ぐ答えを見つけた[[::<::]]
。@#$%^&*などの特殊文字との衝突
交換してください。
SELECT *
FROM table
WHERE keywords REGEXP '[[:<:]]rid[[:>:]]'
これとともに..
SELECT *
FROM table
WHERE keywords REGEXP '([[:blank:][:punct:]]|^)rid([[:blank:][:punct:]]|$)'
後者は一致します(スペース、タブなど)|| (コンマ、ブラケットなど)||行の開始/終了。より「完成した」単語境界一致。
ワイルドカードマーカーでlike
を使用して、可能性(開始時、終了時、中間、単独)をキャッチできます。次のようなもので十分です。
何とか何とかを選択します。「rid%」のような列、「%rid」のような列、「%rid%」のような列、またはcolumn =「rid」
単語の境界で正規表現を使用しますが、アクセントを区別しない検索も必要な場合は、REGEXPはシングルバイト演算子であるため、utf8_general_ci照合を使用する価値はないことに注意してください。一致はアクセントを区別しません。
アクセントを区別せず、Word全体を一致させるには、(非推奨)PHP function sql_regcase()と同じ方法で記述されたWordを指定します。
実際には:
utf8_general_ciでは、大文字と小文字を区別せずに等値(WHEREフィールド=値)を検索できますが、Word一致全体を指定することはできません(Word境界マーカーは認識されません)
LIKEを使用すると、大文字と小文字を区別せずに検索できますが、可能な単語境界文字のすべての組み合わせを手動で指定する必要があります(単語境界マーカーは認識されません)
単語境界[[:<:]]および[[:>:]]は、単一バイト関数であるREGEXPでサポートされているため、アクセントを区別しない検索を実行しません。
解決策は、REGEXXPをWordの境界で使用し、Wordをsql_regcaseのように変更することです。
select * from table where Locate('rid ', FieldToSearch) > 0
or Locate(' rid', FieldToSearch) > 0
これにより、スペースの前後にある場所を取り除くことができます。、?!を考慮してアプローチを拡張できます。など、エレガントではありませんが簡単です。
これは私がこれまでに思いついた最高の答えです:
SELECT * FROM table
WHERE keywords REGEXP '^rid[ $]' OR keywords REGEXP ' rid[ $]'
私はそれを次のように単純化したでしょう。
SELECT *
FROM table
WHERE keywords REGEXP '[^ ]rid[ $]'
[^]は、「行頭またはスペース」ではなく、「スペースではない」という特別な意味を持ちます。
REGEXPは複数のLIKE条件とどのように比較されますか? (このアプリのパフォーマンスは重要ではありません。)