web-dev-qa-db-ja.com

MySQL-select内で変数を定義し、同じselect内で使用します

このようなことをする可能性はありますか?

SELECT 
    @z:=SUM(item),
    2*@z
FROM
    TableA;

2列目は常にNULLになります。奇妙なことは、次のようなことをしながら

SELECT 
    @z:=someProcedure(item),
    2*@z
FROM
    TableA;

すべてが期待どおりに機能します。どうして?

23
user2370579

MySQL ドキュメント は、これに関して非常に明確です:

一般的なルールとして、ユーザー変数に値を割り当てたり、同じステートメント内で値を読み取ったりしないでください。期待どおりの結果が得られる場合がありますが、これは保証されません。ユーザー変数を含む式の評価の順序は未定義であり、特定のステートメントに含まれる要素に基づいて変更される場合があります。さらに、この順序は、MySQLサーバーのリリース間で同じであるとは限りません。 SELECT @a、@a:= @ a + 1、...では、MySQLは最初に@aを評価し、次に割り当てを行うと考えるかもしれません。ただし、ステートメントを変更すると(たとえば、GROUP BY、HAVING、またはORDER BY句を追加することにより)、MySQLは評価の順序が異なる実行プランを選択する場合があります。

サブクエリを使用して、必要な処理を実行できます。

select @z, @z*2
from (SELECT @z:=sum(item)
      FROM TableA
     ) t;
28
Gordon Linoff

Mysql 5.5で動作します

select @code:=sum(2), 2*@code

+---------------+---------+
| @code:=sum(2) | 2*@code |
+---------------+---------+
|             2 |       4 |
+---------------+---------+
3
Ravi Parekh
mysql> select @z := sum(5), if(@z := sum(5), 2*@z, 0) ;
+--------------+------------------------------+
| @z := sum(5) | if(@z := sum(5), 2*@z, null) |
+--------------+------------------------------+
|            5 |                           10 |
+--------------+------------------------------+

ifステートメントで2*@zをラップすると、追加の計算の前にsumが実行されることが保証されます。

0
pala_