MySQL:在同一 SELECT 语句中重新使用用户定义的变量

标签 mysql variables select user-defined

我在 stackoverflow 中进行了搜索,但没有找到我的问题的确切答案,所以如果可以,请帮助我。

我“想要”构建这样的 SQL 语句:

SELECT
  @tax1 := (complicated calculation formula),
  @owe := (another complicated calculation formula),
  IF(@owe=0, 0,@tax1/@owe)
FROM ...

但是,在 MySQL 的文档中关于 user-defined variables ,它建议不要这样做:

As a general rule, you should never assign a value to a user variable and read the value within the same statement. You might get the results you expect, but this is not guaranteed. The order of evaluation for expressions involving user variables is undefined and may change based on the elements contained within a given statement; in addition, this order is not guaranteed to be the same between releases of the MySQL Server. In SELECT @a, @a:=@a+1, ..., you might think that MySQL will evaluate @a first and then do an assignment second. However, changing the statement (for example, by adding a GROUP BY, HAVING, or ORDER BY clause) may cause MySQL to select an execution plan with a different order of evaluation.

我的目标是避免复制和粘贴那些非常复杂的公式,因为它会影响可读性,如果公式每次都发生变化,我需要确保它在所有地方都发生了变化 - 但我确实知道这样做,它'会工作得很好。

此外,我知道 ALIAS 不起作用,因为别名仅在 GROUP BY、HAVING 和 ORDER 子句中起作用。

我在其他一些帖子中读到先做一个子查询来先计算@tax1 和@owe,然后使用另一个查询来组合结果。但我认为性能可能不如简单地就地复制和粘贴这些公式。

有没有人有任何建议他们会做什么?还是我在可读性和性能之间难以抉择?

提前致谢。

最佳答案

是的,在没有用户变量的 SQL 中执行此操作的唯一方法是编写一个派生表子查询。然后您可以使用列别名来引用那些复杂表达式的结果:

SELECT tax1, owe, IF(owe=0, 0,tax1/owe) AS ratio
FROM (
  SELECT
    (complicated calculation formula) AS tax1,
    (another complicated calculation formula) AS owe
  FROM ...
) AS _sub

MySQL 在优化子查询时存在一些问题,但派生表的情况并不是最糟糕的情况之一。

关于 MySQL 和子查询的警告是关于在 WHERE 子句中的范围条件中使用子查询。 MySQL 不能确定子查询是常量,它会重复地重新评估子查询作为一个依赖子查询,即使这不是必需的。

关于MySQL:在同一 SELECT 语句中重新使用用户定义的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9724397/

相关文章:

java - 如何用java中的变量替换硬编码数字 - mysql代码

mysql - 寻址三个表 : How many from A are not in B or C? 的 MySQL 查询

php - WordPress 和 SQL - 如果列值不存在,则从另一个表更新和插入

javascript - jquery - 变量作为函数的参数

CSS calc() 与多个单位相乘

java - 为变量赋值

oracle - ORACLE中多列的总和

sql - 即使将最大数据包增加到 128M,MySQL 服务器也消失了?

javascript - 使用 jquery 操作选择框

vb.net - Select Case with "Is"operator