web-dev-qa-db-fra.com

MySQL - Définissez une variable dans select et utilisez-la dans le même select

Est-il possible de faire quelque chose comme ça?

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

Je reçois toujours NULL pour la deuxième colonne. La chose étrange est que, tout en faisant quelque chose comme

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

tout fonctionne comme prévu. Pourquoi?

22
user2370579

MySQL documentation est assez clair à ce sujet:

En règle générale, vous ne devez jamais attribuer une valeur à une variable utilisateur et lisez la valeur dans la même déclaration. Vous pourriez obtenir le résultats que vous attendez, mais cela n’est pas garanti. L'ordre de l'évaluation des expressions impliquant des variables utilisateur est indéfinie et peut changer en fonction des éléments contenus dans une déclaration donnée; De plus, il n'est pas garanti que cet ordre soit le même entre versions du serveur MySQL. Dans SELECT @a, @a: = @ a + 1, ..., vous pourriez pense que MySQL évaluera d'abord @a, puis effectuera un travail seconde. Toutefois, si vous modifiez l'instruction (par exemple, en ajoutant une clause GROUP BY, HAVING ou ORDER BY), MySQL pourra sélectionner un plan d’exécution avec un ordre d’évaluation différent.

Vous pouvez faire ce que vous voulez en utilisant une sous-requête:

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

Fonctionne dans 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 |
+--------------+------------------------------+

Je pense qu'en encapsulant le 2*@z dans l'instruction if, vous vous assurez que la sum est effectuée AVANT le calcul supplémentaire.

0
pala_