Bạn không thể tham chiếu bí danh ngoại trừ trong ORDER BY vì SELECT là mệnh đề cuối cùng thứ hai được đánh giá. Hai cách giải quyết:
SELECT BalanceDue FROM (
SELECT (InvoiceTotal - PaymentTotal - CreditTotal) AS BalanceDue
FROM Invoices
) AS x
WHERE BalanceDue > 0;
Hoặc chỉ lặp lại biểu thức:
SELECT (InvoiceTotal - PaymentTotal - CreditTotal) AS BalanceDue
FROM Invoices
WHERE (InvoiceTotal - PaymentTotal - CreditTotal) > 0;
Tôi thích cái sau hơn. Nếu biểu thức cực kỳ phức tạp (hoặc tốn kém để tính toán), bạn có thể nên xem xét một cột được tính toán (và có thể vẫn tồn tại) thay vào đó, đặc biệt nếu nhiều truy vấn tham chiếu đến cùng một biểu thức này.
Tái bút rằng nỗi sợ hãi của bạn dường như không có cơ sở. Trong ví dụ đơn giản này, SQL Server đủ thông minh để chỉ thực hiện phép tính một lần, mặc dù bạn đã tham chiếu nó hai lần. Đi trước và so sánh các kế hoạch; bạn sẽ thấy chúng giống hệt nhau. Nếu bạn gặp trường hợp phức tạp hơn trong đó bạn thấy biểu thức được đánh giá nhiều lần, vui lòng đăng truy vấn phức tạp hơn và các kế hoạch.
Dưới đây là 5 truy vấn mẫu mà tất cả đều mang lại cùng một kế hoạch thực thi:
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;
Kế hoạch kết quả cho tất cả năm truy vấn: