Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Alias ​​odniesienia (obliczany w SELECT) w klauzuli WHERE

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ń:



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL Server zablokował dostęp do procedury „sys.sp_OACreate” składnika „Ole Automation Procedures”

  2. Jak włączyć wyjście RPC za pomocą T-SQL

  3. Uzyskaj AVG ignorując wartości Null lub Zero

  4. Jak wypisać wszystkie daty między dwiema datami?

  5. Wykonywanie procedury składowanej przy użyciu struktury encji