「where」句で大文字と小文字を区別しないSQLクエリ(MS SQL Server)を作成するにはどうすればよいですか?
SELECT * FROM myTable WHERE myField = 'sOmeVal'
ケースを無視して結果を返したい
回答:
SQL Serverデータベースの既定の構成では、文字列の比較では大文字と小文字が区別されません。データベースが(代替照合を使用して)この設定を上書きする場合は、クエリで使用する照合の種類を指定する必要があります。
SELECT * FROM myTable WHERE myField = 'sOmeVal' COLLATE SQL_Latin1_General_CP1_CI_AS
私が提供した照合は単なる例であることに注意してください(ただし、おそらく問題なく機能します)。SQL Server照合のより完全な概要は、ここにあります。
UPPER
か、LOWER
使用して、その後ケースをLIKE
検索しますか?
通常、文字列の比較では大文字と小文字は区別されません。データベースで大文字と小文字を区別する照合順序が構成されている場合は、大文字と小文字を区別しない照合順序を強制的に使用する必要があります。
SELECT balance FROM people WHERE email = 'billg@microsoft.com'
COLLATE SQL_Latin1_General_CP1_CI_AS
私は他の場所で別の解決策を見つけました。つまり、使用する
upper(@yourString)
しかし、ここの誰もが、SQL Serverでは、とにかく大文字と小文字を区別しないので、それは問題ではないと言っていますか?私たちのデータベースでは大文字と小文字が区別されると確信しています。
(からトップ2の回答アダム・ロビンソンとAndrejs Cainikovsは、彼らは技術的に作業を行うことで)、正しいみかん、ちょっとですが、その説明は間違っているので、多くの場合、誤解を招くことができます。たとえば、SQL_Latin1_General_CP1_CI_AS
照合は多くの場合機能しますが、大文字と小文字を区別しない適切な照合であると見なすべきではありません。実際、OPが大文字と小文字を区別する(または場合によってはバイナリの)照合順序でデータベースで動作していることを考えると、OPは非常に多くのインストール(特にOSにインストールされているもの)のデフォルトである照合順序を使用していないことがわかります)言語として英語を使用して:SQL_Latin1_General_CP1_CI_AS
。確かに、OPはを使用している可能性がありますSQL_Latin1_General_CP1_CS_AS
が、VARCHAR
データの場合、データの損失につながる可能性があるため、コードページを変更しないことが重要です。これは、照合のロケール/カルチャによって制御されます(つまり、Latin1_General、フランス語、ヘブライ語など)。下記のポイント9をご覧ください。
他の4つの答えはさまざまな程度で間違っています。
読者が最も適切で効率的な選択を行えるように、ここですべての誤解を明らかにします。
使用しないでくださいUPPER()
。それは完全に不要な余分な作業です。COLLATE
句を使用します。どちらの場合も文字列の比較を行う必要がありますが、を使用UPPER()
すると、大文字のマッピングがあるかどうかを文字ごとに確認してから変更する必要があります。そして、あなたは両側でこれを行う必要があります。追加COLLATE
は、デフォルトで行われていたものとは異なるルールのセットを使用してソートキーを生成するように処理を指示するだけです。このテストスクリプト(PasteBin)で証明されCOLLATE
ているように、使用する方が、使用するよりも間違いなく効率的です(または、その単語が好きな場合は「パフォーマンスが高い」:) 。UPPER()
@Dannyの回答について@Ceiscが指摘した問題もあります。
一部の言語では、変換はラウンドトリップしません。つまり、LOWER(x)!= LOWER(UPPER(x))です。
トルコ語の大文字の「İ」が一般的な例です。
いいえ、少なくともこのコンテキストでは、照合はデータベース全体の設定ではありません。データベースレベルのデフォルトの照合があり、COLLATE
句を指定しない変更および新しく作成された列のデフォルトとして使用されます(これは、この一般的な誤解が原因である可能性があります)が、そうでない限り、クエリに直接影響しません。文字列リテラルと変数を他の文字列リテラルと変数と比較するか、データベースレベルのメタデータを参照しています。
いいえ、照合はクエリごとではありません。
照合は、クエリごとではなく、述語(つまり、何かオペランド何か)または式ごとに行われます。そして、これはWHERE
句だけでなくクエリ全体にも当てはまります。これには、JOIN、GROUP BY、ORDER BY、PARTITIONBYなどが含まれます。
いいえ、次の理由でVARBINARY
(などconvert(varbinary, myField) = convert(varbinary, 'sOmeVal')
)に変換しないでください。
_BIN2
SQL Server 2008以降を使用している場合は、で終わるものを使用してください。それ以外の場合は、で終わるものを使用するしかありません_BIN
。データがそうである場合、NVARCHAR
それらはすべて同じであるため、どのロケールを使用してもかまいませんLatin1_General_100_BIN2
。したがって、常に機能します。データがある場合VARCHAR
、あなたはデータ(例えば、現在あるのと同じロケールを使用する必要がありLatin1_General
、French
、Japanese_XJIS
ロケールが使用されているコードページを決定し、コードページを変更するとデータ(データの損失)を変えることができるので、など)。CONVERT()
に使用すると、デフォルト値の30が使用されます。危険なのは、文字列が30バイトを超える可能性がある場合、文字列がサイレントに切り捨てられ、この述語から誤った結果が得られる可能性があることです。いいえ、LIKE
常に大文字と小文字が区別されるとは限りません。参照されている列の照合、変数が文字列リテラルと比較される場合はデータベースの照合、またはオプションのCOLLATE
句で指定された照合を使用します。
LCASE
SQLServerの関数ではありません。OracleまたはMySQLのいずれかであるように見えます。それともVisualBasic?
質問のコンテキストは列を文字列リテラルと比較することであるため、インスタンスの照合(「サーバー」と呼ばれることが多い)もデータベースの照合もここでは直接的な影響はありません。照合順序は列ごとに格納され、各列は異なる照合順序を持つことができ、それらの照合順序はデータベースのデフォルトの照合順序またはインスタンスの照合順序と同じである必要はありません。確かに、インスタンス照合はCOLLATE
、データベースの作成時に句が指定されていない場合に、新しく作成されたデータベースがデフォルトの照合として使用するデフォルトです。同様に、データベースのデフォルトの照合順序は、COLLATE
句が指定されていない場合に変更または新しく作成された列が使用するものです。
大文字と小文字を区別しない照合を使用する必要があります。それ以外の点では、列の照合と同じです。次のクエリを使用して、列の照合順序を検索します(テーブルの名前とスキーマ名を変更します)。
SELECT col.*
FROM sys.columns col
WHERE col.[object_id] = OBJECT_ID(N'dbo.TableName')
AND col.[collation_name] IS NOT NULL;
次に、をに変更_CS
します_CI
。だから、Latin1_General_100_CS_AS
になりLatin1_General_100_CI_AS
ます。
列がバイナリ照合(_BIN
またはで終わる_BIN2
)を使用している場合は、次のクエリを使用して同様の照合を見つけます。
SELECT *
FROM sys.fn_helpcollations() col
WHERE col.[name] LIKE N'{CurrentCollationMinus"_BIN"}[_]CI[_]%';
たとえば、列がを使用していると仮定してJapanese_XJIS_100_BIN2
、次のようにします。
SELECT *
FROM sys.fn_helpcollations() col
WHERE col.[name] LIKE N'Japanese_XJIS_100[_]CI[_]%';
照合、エンコーディングなどの詳細については、以下をご覧ください:照合情報
いいえ、使用LIKE
するだけでは機能しません。LIKE
指定されたパターンに完全に一致する値を検索します。この場合LIKE
、テキスト「sOmeVal」のみが検索され、「someval」は検索されません。
実用的な解決策は、LCASE()
関数を使用することです。LCASE('sOmeVal')
テキストの小文字の文字列を取得します: 'someval'。比較の両側でこの関数を使用すると、次のように機能します。
SELECT * FROM myTable WHERE LCASE(myField) LIKE LCASE('sOmeVal')
このステートメントは2つの小文字の文字列を比較するため、「sOmeVal」は「someval」の他のすべての表記と一致します(たとえば、「Someval」、「sOMEVAl」など)。
LCASE()
、SQL Serverにはなかったと思います(少なくとも私が見ることはできません)。この答えは、まったく異なるRDBMSに対するものだと思います。文字列の比較の説明については、私の回答を参照してください。
大文字と小文字を区別して、次のようなvarbinaryにキャストできます。
SELECT * FROM myTable
WHERE convert(varbinary, myField) = convert(varbinary, 'sOmeVal')
どのデータベースを使用していますか?MS SQL Serverでは、データベース全体の設定ですが、COLLATEキーワードを使用してクエリごとに上書きすることもできます。
WHERE
ステートメントの最後に1回追加するだけでよく、すべてのWHERE
句に影響しますよね?