Non è possibile fare riferimento a un alias tranne in ORDER BY perché SELECT è la penultima etichetta valutata. Due soluzioni:
SELECT BalanceDue FROM (
SELECT (InvoiceTotal - PaymentTotal - CreditTotal) AS BalanceDue
FROM Invoices
) AS x
WHERE BalanceDue > 0;
Oppure è sufficiente ripetere l'espressione:
SELECT (InvoiceTotal - PaymentTotal - CreditTotal) AS BalanceDue
FROM Invoices
WHERE (InvoiceTotal - PaymentTotal - CreditTotal) > 0;
preferisco la seconda. Se l'espressione è estremamente complessa (o costosa da calcolare), dovresti probabilmente considerare una colonna calcolata (e forse persistente), soprattutto se molte query si riferiscono a questa stessa espressione.
PS le tue paure sembrano infondate. In questo semplice esempio, SQL Server è abbastanza intelligente da eseguire il calcolo solo una volta, anche se l'hai fatto riferimento due volte. Vai avanti e confronta i piani; vedrai che sono identici. Se hai un caso più complesso in cui vedi l'espressione valutata più volte, pubblica la query più complessa e i piani.
Qui ci sono 5 esempio query che tutto cedere lo stesso identico piano di esecuzione:
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;
Con conseguente piano per tutte e cinque le domande:
fonte
2012-06-25 00:54:29
grazie mille Aaron! –
Wow. SQL Server è abbastanza intelligente da eseguire il calcolo solo una volta – alternatefaraz
Wow questa è una risposta di altissima qualità! – Siddhartha