除了在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;
生成的計劃:
非常感謝亞倫! –
哇。 SQL Server足夠聰明,只能執行一次計算 – alternatefaraz
哇這是一個非常高質量的答案! – Siddhartha