Nie można odwoływać się do aliasu z wyjątkiem ORDER BY, ponieważ SELECT jest przedostatnią klauzulą, która jest oceniana. Dwa obejścia:
SELECT BalanceDue FROM (
SELECT (InvoiceTotal - PaymentTotal - CreditTotal) AS BalanceDue
FROM Invoices
) AS x
WHERE BalanceDue > 0;
Lub po prostu powtórz wyrażenie:
SELECT (InvoiceTotal - PaymentTotal - CreditTotal) AS BalanceDue
FROM Invoices
WHERE (InvoiceTotal - PaymentTotal - CreditTotal) > 0;
Wolę to drugie. Jeśli wyrażenie jest bardzo złożone (lub kosztowne do obliczenia), prawdopodobnie powinieneś zamiast tego rozważyć kolumnę obliczaną (i być może utrwaloną), zwłaszcza jeśli wiele zapytań odwołuje się do tego samego wyrażenia.
PS Twoje obawy wydają się bezpodstawne. Przynajmniej w tym prostym przykładzie SQL Server jest wystarczająco inteligentny, aby wykonać obliczenia tylko raz, nawet jeśli odwołano się do niego dwukrotnie. Śmiało i porównaj plany; zobaczysz, że są identyczne. Jeśli masz bardziej złożony przypadek, w którym wyrażenie zostało ocenione wielokrotnie, opublikuj bardziej złożone zapytanie i plany.
Oto 5 przykładowych zapytań, z których wszystkie dają dokładnie taki sam plan wykonania:
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;
Wynikowy plan dla wszystkich pięciu zapytań: