SQL SELECT语句子查询内无法使用列别名问题咨询
报错产生原因
SQL查询遵循固定的逻辑执行顺序,SELECT子句中定义的列别名,是在FROM/JOIN/WHERE/GROUP BY/HAVING等所有前置阶段执行完成后,才会在投影计算阶段生成。同层级SELECT里的所有表达式是并行计算语义,不存在“逐行定义、逐行生效”的逻辑,因此同层级刚定义的列别名,无法被同层级SELECT中的其他计算表达式直接引用(只有执行顺序在SELECT之后的ORDER BY子句,可以正常引用这些别名)。
你写的InvoiceTotal - (SELECT InvoiceAverage)部分,括号内是一个独立的标量子查询,这个子查询没有指定任何来源表,既无法访问同层级SELECT刚定义的InvoiceAverage别名,也找不到对应字段的实际存储位置,本身就是不符合多数SQL方言语法要求的不完整查询,因此会抛出如下错误:
Invalid column name 'InvoiceAverage'.
正确修改方案
推荐使用CROSS JOIN预先计算全局发票平均值,这种写法只会执行一次全表平均值计算,查询性能更好,逻辑也更清晰:
SELECT i.InvoiceId, i.InvoiceTotal, avg_stat.InvoiceAverage, i.InvoiceTotal - avg_stat.InvoiceAverage AS InvoiceDifference FROM Invoices i CROSS JOIN ( -- 预计算全表平均发票额 SELECT AVG(InvoiceTotal) AS InvoiceAverage FROM Invoices ) AS avg_stat;
如果不想使用关联写法,也可以直接在差值计算处重复写平均值标量子查询,多数数据库的优化器会自动识别重复子查询做缓存处理,不会真的重复扫描全表计算平均值:
SELECT InvoiceId, InvoiceTotal, (SELECT AVG(InvoiceTotal) FROM Invoices) AS InvoiceAverage, InvoiceTotal - (SELECT AVG(InvoiceTotal) FROM Invoices) AS InvoiceDifference FROM Invoices;
内容的提问来源于stack exchange,提问作者Kenzo
相关产品推荐
相关产品推荐

