Ви не можете посилатися на псевдонім, за винятком порядку 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;
Результатний план для всіх п'яти запитів: