と の 2 つのテーブルが存在するusers
としgroups
ます。
ユーザーがテキストを入力すると、そのテキストを名前に含むユーザーとグループの両方が結果に含まれる「単純な検索」を提供するにはどうすればよいでしょうか?
検索の結果は、2 つのタイプを区別する必要があります。
トリックは、UNION
a をリテラル文字列と組み合わせて、返される「オブジェクト」のタイプを決定することです。ほとんどの場合 (?)、UNION ALL はより効率的であり、サブクエリで重複が必要でない限り使用する必要があります。次のパターンで十分です。
SELECT "group" type, name
FROM groups
WHERE name LIKE "%$text%"
UNION ALL
SELECT "user" type, name
FROM users
WHERE name LIKE "%$text%"
注:昨日この問題に遭遇し、適切な解決策が見つからず、この方法を使用したため、自分で回答を追加しました。誰かがより良いアプローチを持っている場合は、お気軽に追加してください。
「UNION ALL」を使用すると、データベースは重複を削除しようとしません.2つのクエリ間で重複することはありません(最初の列が異なるため).UNION ALLの方が高速です.
(削除したい各クエリ内に重複がないことを前提としています)
LIKE を使用すると、LIKE コンパレータが % で始まるたびにテーブル スキャンが必要になるため、多くの問題が発生します。これにより、SQLはすべての行をチェックし、比較に使用している文字列を介してバイトごとに機能します。開始時はこれで問題ないかもしれませんが、すぐにスケーリングの問題が発生します。
これを処理するより良い方法は、全文検索を使用することです。これはより複雑なオプションですが、非常に大規模なデータベースの場合により良い結果が得られます。次に、Bobby Jack が提供したサンプルの機能バージョンをUNION ALL
2 つの結果セットに一緒に使用して、結果を表示できます。
別の追加をお勧めします
SELECT "group" type, name
FROM groups
WHERE UPPER(name) LIKE UPPER("%$text%")
UNION ALL
SELECT "user" type, name
FROM users
WHERE UPPER(name) LIKE UPPER("%$text%")
最初に $text を大文字に変換するか、クエリでそれを行うことができます。このようにして、大文字と小文字を区別しない検索を取得します。