sql >> Database >  >> RDS >> Sqlserver

Referentie-alias (berekend in SELECT) in WHERE-component

U kunt niet naar een alias verwijzen, behalve in ORDER BY, omdat SELECT de op één na laatste clausule is die wordt geëvalueerd. Twee oplossingen:

SELECT BalanceDue FROM (
  SELECT (InvoiceTotal - PaymentTotal - CreditTotal) AS BalanceDue
  FROM Invoices
) AS x
WHERE BalanceDue > 0;

Of herhaal gewoon de uitdrukking:

SELECT (InvoiceTotal - PaymentTotal - CreditTotal) AS BalanceDue
FROM Invoices
WHERE  (InvoiceTotal - PaymentTotal - CreditTotal)  > 0;

Ik geef de voorkeur aan het laatste. Als de uitdrukking extreem complex is (of duur om te berekenen), moet u waarschijnlijk een berekende kolom overwegen (en misschien blijven bestaan), vooral als veel zoekopdrachten naar dezelfde uitdrukking verwijzen.

PS je angsten lijken ongegrond. In dit eenvoudige voorbeeld is SQL Server tenminste slim genoeg om de berekening maar één keer uit te voeren, ook al heb je er twee keer naar verwezen. Ga je gang en vergelijk de plannen; je zult zien dat ze identiek zijn. Als je een complexere zaak hebt waarbij je de uitdrukking meerdere keren ziet geëvalueerd, post dan de meer complexe vraag en de plannen.

Hier zijn 5 voorbeeldquery's die allemaal exact hetzelfde uitvoeringsplan opleveren:

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;

Resulterend plan voor alle vijf zoekopdrachten:



  1. LPAD in SQL Server 2008

  2. Hoe een volledige externe join te doen in MySQL

  3. Geen Entity Framework-provider gevonden voor 'MySql.Data.MySqlClient' ADO.NET-provider

  4. Wijzigen op grote tafel in RDS Oplossing voor tabel vol Fout