質問: で紹介されてる分析関数をMySQLのユーザ変数で代用するSelect文は、 本番環境で使用するSelect文で、使っていいものなのでしょうか? たとえば、リンク先のStackOverFlowの下記のSelect文において、 ``` SELECT id_student, id_class, grade, @student:=CASE WHEN @class <> id_class THEN 0 ELSE @student+1 END AS rn, @class:=id_class AS clset FROM (SELECT @student:= -1) s, (SELECT @class:= -1) c, (SELECT * FROM mytable ORDER BY id_class, id_student) t ``` たとえば、 全ての行の@class:=id_class という列を評価されてから、 全ての行の@student:=CASE WHEN @class <> id_class THEN 0 ELSE @student+1 END AS rn を評価するとしたら、結果は期待した通りにならないし そもそも ORDER BY id_class, id_studentの順番で、 かつSelect句の左から右にユーザ変数が評価されない限り 期待した結果にならないと思います。 そして、 MySQLのマニュアルにも、ユーザ変数の評価順序は、定義されていないと記載されています。 http://download.nust.na/pub6/mysql/doc/refman/5.1-olh/ja/user-variables.html >ユーザー変数の評価順序は定義されておらず、 >与えられたクエリー内の要素に基づいて変更されることがあります。 >SELECT @a, @a := @a+1 ...では、MySQL は@a を先に評価し次に割り当てが実行されるように見えますが、 >クエリーの変更(たとえば GROUP BY、HAVING または ORDER BY 節による変更) >は評価順序を変更する可能性があります。 >基本的な規則は、ステートメントの一部でユーザー変数値を割り当てないことおよび >同一ステートメント内の他部分で同じ変数を使用しないことです。 >期待通りの結果を得られるかもしれませんが、これは確約されていません。 上記の理由から select文でユーザ変数を複数回使って、 分析関数を代用するSelect文は、結果が保証されないのだから 本番環境などでは、全く使い物にならないというのが私の認識なのですが、 みなさんはどうでしょうか?
回答: MySQLのマニュアルと OracleACEのAketiJyuuzouさんとyoku0825さんと 日本オラクルの木村明治さんによると MySQLのユーザ変数は評価順序が未定義です。 なので、分析関数と同じ結果が出ることが保証されません。 結果が保証されないといえば、 OrderBy句がないと出力順が保証されないのは有名ですね。