大多数のステートメントでは、MySQL がどの照合順序を使用して比較演算を行うかは明確になっています。たとえば、次の場合、照合順序がカラム charset_name
の照合順序であることは明らかです。
SELECT x FROM T ORDER BY x;
SELECT x FROM T WHERE x = x;
SELECT DISTINCT x FROM T;
ただし、複数のオペランドがあると、あいまいさが生じることがあります。例:
SELECT x FROM T WHERE x = 'Y';
カラム x
の照合順序を使用して比較したほうがよいでしょうか、それとも文字列リテラル 'Y'
の照合順を使用して比較したほうがよいででしょうか。x
と 'Y'
の両方に照合順序がありますが、どちらの照合順序が優先されるでしょうか。
標準 SQL では、「強制性」ルールと呼ばれていた方法で上記の問題を解決しています。MySQL は次のように強制性値を割り当てます。
明示的な
COLLATE
句の強制性は 0 です。(強制性がまったくありません。)照合順序の異なる 2 つの文字列を連結すると強制性は 1 になります。
カラムまたはストアドルーチンのパラメータまたはローカル変数の照合順序の強制性は 2 です。
「システム定数」 (
USER()
またはVERSION()
などの関数で返される文字列) の強制性は 3 です。リテラルの照合順序の強制性は 4 です。
NULL
またはNULL
から派生した式の強制性 5 です。
MySQL は、次のルールとともに強制性値を使用して、あいまいさを解決します。
強制性値がもっとも低い照合順序を使用します。
-
両方の側で強制性が同じ場合は、次のようになります。
両方の側が Unicode であるか、両方の側が Unicode ではない場合は、エラーになります。
-
どちらかの側に Unicode 文字セットがあり、もう一方の側に Unicode 以外の文字セットがある場合、Unicode 文字セットの側が優先され、Unicode 以外の側に自動文字セット変換が適用されます。たとえば、次のステートメントはエラーを返しません。
SELECT CONCAT(utf8_column, latin1_column) FROM t1;
これは、
utf8
の文字セットと、utf8_column
と同じ照合順序を含む結果を返します。連結する前に、latin1_column
の値は自動的に、utf8
に変換されます。 同じ文字セットのオペランドだが、
_bin
照合順序と_ci
または_cs
照合順序が混在したオペランドを使用した演算の場合、_bin
照合順序が使用されます。これは、対象がデータ型でなく照合順序である点を除けば、非バイナリ文字列とバイナリ文字列が混在した演算でオペランドがバイナリ文字列に評価される方法に似ています。
自動変換機能は SQL 標準には含まれていません。ただし、どの文字セットも (サポートされている文字に関して) Unicode の「サブセット」であることが SQL 標準のドキュメントに記載されています。「スーパーセットに適用されるものはサブセットにも適用される」というよく知られた原則があるので、Unicode の照合順序は Unicode 以外の文字列との比較にも適用できると考えられます。
例:
比較 | 使用される照合順序 |
---|---|
column1 = 'A' |
column1 の照合順序を使用します |
column1 = 'A' COLLATE x |
'A' COLLATE x の照合順序を使用します |
column1 COLLATE x = 'A' COLLATE y |
エラー |
COERCIBILITY()
関数を使用すると、文字列式の強制性を特定できます。
mysql> SELECT COERCIBILITY('A' COLLATE latin1_swedish_ci);
-> 0
mysql> SELECT COERCIBILITY(VERSION());
-> 3
mysql> SELECT COERCIBILITY('A');
-> 4
セクション12.14「情報関数」を参照してください。
式 CONCAT(1, 'abc')
での引数 1
に対して行われる変換など、数値または時間値の文字列への暗黙の変換の場合、その結果は、character_set_connection
および collation_connection
システム変数で指定された文字セットおよび照合順序を持つ文字 (非バイナリ) 列になります。セクション12.2「式評価での型変換」を参照してください。