引用别名(在SELECT中计算)在WHERE子句中

SELECT (InvoiceTotal - PaymentTotal - CreditTotal) AS BalanceDue FROM Invoices WHERE BalanceDue > 0 --error 

在选定列的列表中设置为variables的计算值“BalanceDue”不能在WHERE子句中使用。

有没有办法呢? 在这个相关的问题中( 在Where子句中使用MySQL Select Statment中的variables ),似乎答案会是,实际上,不,您只需写出计算( 在查询中执行计算)两次,而不是这是令人满意的。

除了在ORDER BY中,你不能引用一个别名,因为SELECT是被评估的第二个最后一个子句。 两种解决方法:

 SELECT BalanceDue FROM ( SELECT (InvoiceTotal - PaymentTotal - CreditTotal) AS BalanceDue FROM Invoices ) AS x WHERE BalanceDue > 0; 

或者重复这个expression:

 SELECT (InvoiceTotal - PaymentTotal - CreditTotal) AS BalanceDue FROM Invoices WHERE (InvoiceTotal - PaymentTotal - CreditTotal) > 0; 

我更喜欢后者。 如果expression式非常复杂(或计算成本高昂),则应该考虑使用计算列(也可能是持久的),特别是在大量查询引用同一个expression式的情况下。

PS你的恐惧似乎没有根据。 在这个简单的例子中,SQL Server足够聪明,只能执行一次计算,即使你已经引用了两次。 继续比较计划; 你会看到他们是相同的。 如果你有一个更复杂的情况下,你看到expression式多次评估,请张贴更复杂的查询和计划。

以下是5个示例查询,它们都产生完全相同的执行计划:

 SELECT LEN(name) + column_id AS x FROM sys.all_columns WHERE LEN(name) + column_id > 30; SELECT x FROM ( SELECT LEN(name) + column_id AS x FROM sys.all_columns ) AS x WHERE x > 30; SELECT LEN(name) + column_id AS x FROM sys.all_columns WHERE column_id + LEN(name) > 30; SELECT name, column_id, x FROM ( SELECT name, column_id, LEN(name) + column_id AS x FROM sys.all_columns ) AS x WHERE x > 30; SELECT name, column_id, x FROM ( SELECT name, column_id, LEN(name) + column_id AS x FROM sys.all_columns ) AS x WHERE LEN(name) + column_id > 30; 

所有五个查询的最终计划:

在这里输入图像说明

你可以使用cross join来做到这一点

 SELECT c.BalanceDue AS BalanceDue FROM Invoices cross join (select (InvoiceTotal - PaymentTotal - CreditTotal) as BalanceDue) as c WHERE c.BalanceDue > 0;