sql >> データベース >  >> RDS >> Sqlserver

WHERE句の参照エイリアス(SELECTで計算)

    SELECTは評価される最後から2番目の句であるため、ORDERBY以外ではエイリアスを参照できません。 2つの回避策:

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

    または、次の式を繰り返します:

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

    私は後者が好きです。式が非常に複雑な場合(または計算にコストがかかる場合)、特に多くのクエリがこの同じ式を参照している場合は、代わりに計算列を検討する必要があります(おそらく永続化されます)。

    PSあなたの恐れは根拠がないようです。少なくともこの単純な例では、SQL Serverは、2回参照したとしても、計算を1回だけ実行するほど賢いです。先に進み、計画を比較します。それらが同一であることがわかります。式が複数回評価されるというより複雑なケースがある場合は、より複雑なクエリと計画を投稿してください。

    以下に、まったく同じ実行プランを生成する5つのクエリ例を示します。

    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;
    

    5つのクエリすべての結果の計画:



    1. MySQLでのREGEXP_LIKE()関数のしくみ

    2. 複合インデックスはいつ使用する必要がありますか?

    3. UNIONALL最適化

    4. MySQLで昨日の日付を取得する方法