MariaDB中如何复用SELECT命名计算结果?哪种写法更高效?
解决SELECT语句中复用计算别名的问题
首先,你遇到的ERROR 1054是因为SQL的执行顺序导致的:数据库会先执行FROM/JOIN和WHERE子句,之后才会处理SELECT里的字段计算和别名赋值。这意味着你在SELECT里定义的result_price别名,在同一条SELECT的其他字段中是无法直接引用的——此时这个别名还没被创建出来。
接下来给你几个可行的解决办法,以及效率对比:
方法1:使用子查询(兼容你的MariaDB版本)
因为你的MariaDB是10.1.38,还不支持CTE(公共表表达式,10.2及以上才支持),所以子查询是最稳妥的方案:
SELECT result_price, (result_price - 30)/30 AS percentage FROM ( SELECT f.price * t.price AS result_price FROM table f JOIN table t ON f.to_id = t.from_id WHERE f.from_id = 12 AND t.to_id = 205 ) AS subquery;
子查询会先计算出result_price,外层查询就可以直接复用这个别名了。
方法2:重复编写计算表达式
这就是你提到的直接重复(f.price * t.price - 30)/30的写法:
SELECT f.price * t.price AS result_price, (f.price * t.price - 30)/30 AS percentage FROM table f JOIN table t ON f.to_id = t.from_id WHERE f.from_id = 12 AND t.to_id = 205;
别担心重复计算的问题——现代数据库(包括你用的MariaDB)的查询优化器会识别到重复的表达式,只会实际计算一次f.price * t.price,然后把结果同时用到两个字段里。
方法3:使用用户变量(不推荐,有潜在风险)
你也可以用用户变量来存储计算结果,但要注意变量赋值的顺序完全依赖于字段的顺序,一旦字段顺序改变就会出错,所以不推荐在生产环境使用:
SELECT @result_price := f.price * t.price AS result_price, (@result_price - 30)/30 AS percentage FROM table f JOIN table t ON f.to_id = t.from_id WHERE f.from_id = 12 AND t.to_id = 205;
效率对比
- 重复表达式和子查询的效率几乎没有区别:MariaDB的优化器会对这两种写法生成类似的执行计划,不会因为重复表达式就多做一次计算。
- 用户变量的写法效率可能略高一点点,但带来的维护风险远大于这点微小的性能提升,所以不建议使用。
如果追求代码可读性,子查询是更好的选择;如果想让SQL更简洁,重复表达式也完全没问题,不会影响性能。
内容的提问来源于stack exchange,提问作者platypusmaximus
相关产品推荐
相关产品推荐

