除了ORDER BY外,您不能引用别名,因为SELECT是第二个被评估的子句。两种解决方法:
SELECT BalanceDue FROM (
SELECT (InvoiceTotal - PaymentTotal - CreditTotal) AS BalanceDue
FROM Invoices
) AS x
WHERE BalanceDue > 0;
或者只是重复表达:
SELECT (InvoiceTotal - PaymentTotal - CreditTotal) AS BalanceDue
FROM Invoices
WHERE (InvoiceTotal - PaymentTotal - CreditTotal) > 0;
我更喜欢后者。如果表达式非常复杂(或计算成本很高),则您可能应该考虑使用计算列(并且可能会保留),尤其是在很多查询都引用同一表达式的情况下。
PS,您的担心似乎没有根据。至少在这个简单的示例中,SQL Server足够聪明,只需要执行一次计算,即使您已经两次引用了它。继续比较计划;您会看到它们是相同的。如果您遇到的情况更为复杂,则该表达式会被多次评估,请发布更复杂的查询和计划。
以下是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;
所有五个查询的结果计划: