MySQL在使用过程中对表达式的评估更改

时间:2017-04-30 09:47:43

标签: mysql

SELECT
    @x := (600  - COUNT(h.challenge_user_historyID)) / 180 AS x,
    CASE
        WHEN (1 > 2)
            THEN 25
        ELSE
            1 + @x
    END AS priority,
    COUNT(h.challenge_user_historyID) AS n_games_actual
FROM campaigns c
LEFT JOIN challenge_user_history h
    ON (c.challengeID = h.challengeID)
GROUP BY c.campaignID
ORDER BY
    priority DESC;


+-------------+------------------+----------------+
|      x      |        priority  | n_games_actual |
+-------------+------------------+----------------+
| 3.000000000 | 4.11110000000000 |             60 |
| 3.222222222 | 4.11110000000000 |             20 |
| 3.333333333 | 4.11110000000000 |              0 |
| 3.111111111 | 4.11110000000000 |             40 |
| 2.777777777 | 4.11110000000000 |            100 |
+-------------+------------------+----------------+

这对我来说很奇怪。如果在评估COUNT()时正确获取n_games_actual x的值(如输出中x的值所示),那么为什么在进行基本相同的计算时会出错在优先权?怎么能纠正这个?

感谢。

1 个答案:

答案 0 :(得分:1)

很好的问题,查询的行为是出乎意料的,但它并不是一个错误。

似乎正在发生的事情是在查询期间未设置@x。它仅在计算完成后设置。它被设置为计算的最后一行,请注意,这可能与结果中的最后一行不同,因为有一个ORDER BY子句在返回结果之前改变了顺序。

可以创建其他查询,其中在查询执行时每行更新变量的值。

关键是MySQL不会在查询中设置变量时作出任何承诺。 User Defined Variables文档指出:

  

作为一般规则,除了在SET语句中,您不应该为用户变量赋值并在同一语句中读取值。

  

涉及用户变量的表达式的评估顺序未定义。

因此,您需要更改查询以避免设置和读取相同的变量,并且它应该按预期工作。