web-dev-qa-db-ja.com

文字列を比較するときにSqlite3を大文字と小文字を区別しないように設定するにはどうすればよいですか?

文字列照合によりsqlite3データベースからレコードを選択したい。しかし、where句で「=」を使用すると、sqlite3では大文字と小文字が区別されることがわかりました。大文字と小文字を区別せずに文字列を比較する方法を教えてもらえますか?

268
quantity

SELECTクエリでCOLLATE NOCASEを使用できます。

SELECT * FROM ... WHERE name = 'someone' COLLATE NOCASE

さらに、SQLiteでは、列定義でcollate nocaseを指定することで、テーブルを作成するときに列の大文字と小文字を区別しないことを示すことができます(他のオプションはbinary(デフォルト)およびrtrimです; here を参照) 。インデックスを作成するときにもcollate nocaseを指定できます。例えば:

テーブルの作成Test 
(
 Text_Value text collat​​e nocase 
); 
 
テスト値への挿入( 'A'); 
テスト値に挿入( 'b'); 
テスト値に挿入( 'C'); 
 
インデックスを作成Test_Text_Value_Index 
 on Test (Text_Value照合nocase); 

Test.Text_Valueを含む式では、大文字と小文字が区別されなくなりました。例えば:

 sqlite> Text_Value = 'B'のテストからText_Valueを選択します; 
 Text_Value 
 ---------------- 
 b 
 
 sqlite> Text_Valueによるテスト順序からText_Valueを選択します; 
 Text_Value 
 ---------------- 
 A 
 b 
 C 
 
 sqlite> Text_Value desc;によるテストオーダーからText_Valueを選択します。 -------------- 
 C 
 b 
 A 
 C

オプティマイザーは、列の大文字と小文字を区別しない検索およびマッチングにインデックスを潜在的に使用することもできます。これは、explain SQLコマンドを使用して確認できます。例:

 sqlite>説明Text_Value = 'b'; 
 addr opcode p1 p2 p3 
 ----------------のテストから選択したText_Valueを説明します-------------- ---------- ---------- ---------------- ----------------- 
 0 Goto 0 16 
 1整数0 0 
 2 OpenRead 1 3 keyinfo(1、NOCASE) 
 3 SetNumColumns 1 2 
 4 String8 0 0 b 
 5 IsNull -1 14 
 6 MakeRecord 1 0 a 
 7 MemStore 0 0 
 8 MoveGe 1 14 
 9 MemLoad 0 0 
 10 IdxGE 1 14 + 
 11列1 0 
 12コールバック1 0 
 13次の1 9 
 14閉じる1 0 
 15停止0 0 
 16トランザクション0 0 
 17 VerifyCookie 0 4 
 18ジャンプ0 1 
 19ヌープ0 0 
443
cheduardo
SELECT * FROM ... WHERE name = 'someone' COLLATE NOCASE
144
Craz

次のようにできます:

SELECT * FROM ... WHERE name LIKE 'someone'

(ソリューションではありませんが、場合によっては非常に便利です)

LIKE演算子はパターン一致比較を行います。右側のオペランドにはパターンが含まれ、左側のオペランドにはパターンと一致する文字列が含まれます。パーセント記号( "%")inパターンは、文字列内の0個以上の文字のシーケンスに一致します。パターン内の下線(「_」)は、文字列内の任意の1文字に一致しますその他の文字一致それ自体またはその小文字/大文字同等(大文字と小文字を区別しない一致)(バグ:SQLiteはASCII文字の大文字と小文字のみを認識しますLIKE演算子は、ASCIIの範囲を超えるUnicode文字の大文字と小文字を区別します。たとえば、式 'a' LIKE 'A'はTRUEですが、 'æ' LIKE 'Æ'はFALSEです。 」

43

これはsqliteに固有のものではありませんが、ただ行うことができます

SELECT * FROM ... WHERE UPPER(name) = UPPER('someone')
39
oscarkuo

別のオプションは、独自のカスタム照合を作成することです。その後、その照合を列に設定するか、選択句に追加できます。順序付けと比較に使用されます。

これを使用して、「VOILA」を「voilà」のように作成できます。

http://www.sqlite.org/capi3ref.html#sqlite3_create_collat​​ion

照合関数は、最初の文字列が2番目の文字列より小さい、等しい、または大きい場合、それぞれ負、ゼロ、または正の整数を返す必要があります。

4
Nick Ericson

あなたの場合に意味があるかもしれないし、そうでないかもしれないもう一つのオプションは、実際にあなたの既存の列の事前に低いスコアの値を持つ別の列を持つことです。これは、SQLite関数LOWER()を使用して設定でき、代わりにこの列でマッチングを実行できます。

明らかに、冗長性と不整合の可能性を追加しますが、データが静的な場合は適切なオプションかもしれません。

2
Magnus W

単純に、SELECTクエリでCOLLATE NOCASEを使用できます。

SELECT * FROM ... WHERE name = 'someone' COLLATE NOCASE
1
Pullat Junaid

同様のクエリを使用して、それぞれの文字列とテーブル値を比較できます。

「それぞれの比較値」のような列名のtable_nameから列名を選択します。

1

列のタイプがcharの場合、スペースでクエリする値を追加する必要があります。この質問 here を参照してください。これに加えて、COLLATE NOCASEまたは他のソリューションのいずれか(upper()など)を使用します。

1
Has AlTaiar

それは私にとって完璧に働いています。 SELECT NAME FROM TABLE_NAME WHERE NAME = 'test Name' COLLATE NOCASE

0
Shohel Rana