Nie można odwoływać się do aliasu za wyjątkiem ORDER BY, ponieważ SELECT jest drugą ostatnią klauzulą, która została oceniona. Dwa obejścia:
SELECT BalanceDue FROM (
SELECT (InvoiceTotal - PaymentTotal - CreditTotal) AS BalanceDue
FROM Invoices
) AS x
WHERE BalanceDue > 0;
Albo tylko powtórzyć wyrażenie:
SELECT (InvoiceTotal - PaymentTotal - CreditTotal) AS BalanceDue
FROM Invoices
WHERE (InvoiceTotal - PaymentTotal - CreditTotal) > 0;
wolę to drugie. Jeśli wyrażenie jest bardzo skomplikowane (lub kosztowne do obliczenia), powinieneś raczej rozważyć kolumnę obliczeniową (i być może utrwaloną) zamiast tego, szczególnie jeśli wiele zapytań odnosi się do tego samego wyrażenia.
PS Twoje obawy wydają się bezpodstawne. W tym prostym przykładzie przynajmniej SQL Server jest wystarczająco inteligentny, aby wykonać obliczenia tylko raz, nawet jeśli odwoływałeś 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 jest wielokrotnie sprawdzane, opublikuj bardziej złożone zapytanie i plany.
Oto 5 przykład odpytuje że wszystko uzyskując dokładnie ten 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;
wynikających plan dla wszystkich pięciu pytań:
Wielkie dzięki Aaron! –
Wow. Serwer SQL jest wystarczająco inteligentny, aby wykonać obliczenia tylko raz. – alternatefaraz
Wow, to odpowiedź bardzo wysokiej jakości! – Siddhartha