89832


SQLである単語を含み、その単語の大文字小文字、全角半角、空白の有無の差を無視したlikeのような絞り込みをしたいです。どのようにＳＱＬ文を書けばいいでしょうか？

例  
ある単語：ABC

以下すべてヒットするデータの例  
ABC  
aBC  
abc  
ABC（全角）  
ａｂｃ （全角）  
Ａｂc (全角半角大文字小文字混合）  
xxxabcyyy (abcを含む)  
a b c（間に空白有）

ヒットしないデータの例  
abdc


CC BY-SA 4.0
2022-07-08T00:41:39.317
89823
2022-07-08T10:50:06.057
18637
question
sql
SQLであいまい検索をする


まず、MySQL や PostgreSQL などの RDBMS
で恒常的にこのような検索をするのはあまりオススメしません。頑張ればできないこともないですが、クエリの実行にインデックスを使いづらいため基本的にフルスキャンになってしまいスロークエリになってしまいがちです。Elasticsearch
など全文検索用のソフトウェアを使うのをオススメします。

「頑張ればできないこともない」というのは、たとえば正規表現でマッチするようにするとある程度ご所望の検索ができます。

例として MySQL だと、`'ABC'` という文字列から `'[aAａＡ][[:blank:]]*[bBｂＢ][[:blank:]]*[cCｃＣ]'`
という正規表現を作って [`regexp`
演算子](https://dev.mysql.com/doc/refman/8.0/en/regexp.html)でマッチを計算するとある程度は検索できます。ただし
MySQL のバージョンによっては多バイト文字が入っていると予想しづらい挙動になる場合があります。マニュアルをご覧ください。

※もしユーザー入力を元に動的に検索するのが必要なのであれば、ReDoS に繋がらないかどうかのチェックも必要でしょう。

また他に考えられる方法として、RDBMS によっては全文検索用の機能が用意されていることがあるので、これが利用できる場合があるかもしれません。たとえば
MySQL には [FULLTEXT インデックス](https://dev.mysql.com/doc/refman/8.0/ja/innodb-
fulltext-
index.html)があります。ただ、スペースを無視してマッチしたいとなるとそのままは利用できなさそうなのと、またもし日本語を含む場合はトークン化が難しいので
[ngram パーサー](https://dev.mysql.com/doc/refman/8.0/ja/fulltext-search-
ngram.html)で頑張ることにするなどの工夫が必要になりそうです。


CC BY-SA 4.0
2022-07-08T01:16:31.837
89824
2022-07-08T10:50:06.057
2022-07-08T10:50:06.057
19110
19110
89823
answer


SQL Serverならば[COLLATE](https://docs.microsoft.com/ja-
jp/sql/t-sql/statements/collations?view=sql-server-
ver16)を使って[照合順序](https://docs.microsoft.com/ja-jp/sql/relational-
databases/collations/collation-and-unicode-support?view=sql-server-
ver16)を指定し、`like`で大文字小文字や全角半角の区別を有効/無効にすることができます。  
(ちなみにSQL Serverの標準設定で大文字小文字、全角半角の区別はしないようです)

途中のスペースを区別しない照合順序はないので、replace関数を使ってスペースを取り除くことによって(インデックスは犠牲になるかもしれませんが)目的は達成できます。

[code]

    select t.my_text
    from  (select 'ABC' my_text union all
           select 'aBC' my_text union all
           select 'abc' my_text union all
           select 'ABC' my_text union all --（全角）
           select 'ａｂｃ' my_text union all --（全角）
           select 'Ａｂc' my_text union all -- (全角半角大文字小文字混合）
           select 'xxxabcyyy' my_text union all -- (abcを含む)
           select 'a b c' my_text --（間に空白有）
          ) t
    where replace(replace(t.my_text, ' ', ''), '　', '') like '%abc%' COLLATE Japanese_CI_AI
    
[/code]

なお、他のデータベースでも正規表現を使って類似の処理を実現できなくもないことは @nekketsuuu
さんの回答の通りですが、SQL規格に正規表現はなく、それぞれのデータベースの拡張機能として実装されています。  
そのため、データベース共通で使えるあいまい検索のSQLは現時点で存在しないはずです。


CC BY-SA 4.0
2022-07-08T04:52:38.413
89832
2022-07-08T06:12:39.110
2022-07-08T06:12:39.110
9820
9820
89823
answer