Sie können nur in ORDER BY auf einen Alias verweisen, da SELECT die vorletzte Klausel ist, die ausgewertet wird. Zwei Problemumgehungen:
SELECT BalanceDue FROM (
SELECT (InvoiceTotal - PaymentTotal - CreditTotal) AS BalanceDue
FROM Invoices
) AS x
WHERE BalanceDue > 0;
Oder wiederholen Sie einfach den Ausdruck:
SELECT (InvoiceTotal - PaymentTotal - CreditTotal) AS BalanceDue
FROM Invoices
WHERE (InvoiceTotal - PaymentTotal - CreditTotal) > 0;
Ich bevorzuge letzteres. Wenn der Ausdruck äußerst komplex ist (oder teuer zu berechnen ist), sollten Sie stattdessen wahrscheinlich eine berechnete Spalte in Betracht ziehen (und möglicherweise beibehalten werden), insbesondere wenn sich viele Abfragen auf denselben Ausdruck beziehen.
PS Ihre Befürchtungen scheinen unbegründet. Zumindest in diesem einfachen Beispiel ist SQL Server intelligent genug, um die Berechnung nur einmal durchzuführen, obwohl Sie zweimal darauf verwiesen haben. Gehen Sie voran und vergleichen Sie die Pläne; Sie werden sehen, dass sie identisch sind. Wenn Sie einen komplexeren Fall haben, in dem der Ausdruck mehrmals ausgewertet wird, senden Sie bitte die komplexere Abfrage und die Pläne.
Hier sind 5 Beispielabfragen, die alle genau den gleichen Ausführungsplan ergeben:
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;
Resultierender Plan für alle fünf Abfragen: