大多数のクエリでは、MySQL
がどの照合順序により比較演算を行うかは明確になっています。たとえば以下の場合、照合順序がカラムx
のカラム照合順序''
になることは明らかです。
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'
の照合順序のどちらがこのクエリで使用されるのでしょうか
標準 SQL
では、「''強制可能''」ルールと呼ばれていた方法で上記の問題を解決しました。これについては、以下の発想が基本となっていますx
と'Y'
の両方に照合順序があるので、どちらの照合順序を優先するかを判断しなければならない。複雑な問題だが、これらのルールでほとんどの状況に対応できる。
明示的な
COLLATE
節の優先順位は0です。(優先されません)
照合順序の異なる文字列 2 つの連結は優先順位が 1。
カラムの照合順序、保存されたルーチンパラメータ、もしくはローカル変数値は優先順位が 2。
「システム定数」 (USER()
またはVERSION()
といったファンクションに返される文字列)
の優先順位は3。
リテラルの照合順序は優先順位が4 。
NULL
もしくはNULL
由来の表現の優先順位は5。
先行する優先順位の値は現MySQLのものである。5.1
これらのルールによって、あいまいさは次のように解消されます。
優先順位が最も低い照合順序を使用する。
双方の優先順位が一致する場合、照合順序が一致しないとエラーとなる。
例:
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
詳しくはこちらをを参照してください。項11.10.3. 「情報関数」