복붙노트

[SQL] 참조 별칭은 WHERE 절에서 (SELECT에서 계산)

SQL

참조 별칭은 WHERE 절에서 (SELECT에서 계산)

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

선택된 열에서의 변수로 설정되고 계산 값 "BalanceDue '는 WHERE 절에 사용될 수 없다.

그것을 할 수있는 방법이 있습니까? 이 관련된 질문에서 (WHERE 절에서 MySQL을 선택 한 Statment의 변수를 사용하여), 답이 될 것 같은, 전혀 사실, 아니, 당신은 단지 계산을 쓸 것 (쿼리에서 해당 계산을 수행)를 두 번 보인다 어떤 만족입니다.

해결법

  1. ==============================

    1.SELECT 평가 년대 초 마지막 절입니다 때문에 ORDER BY를 제외 별칭을 참조 할 수 없습니다. 두 가지 해결 방법 :

    SELECT 평가 년대 초 마지막 절입니다 때문에 ORDER BY를 제외 별칭을 참조 할 수 없습니다. 두 가지 해결 방법 :

    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는 두 번을 참조했습니다에도 불구하고, 한 번만 계산을 수행하려면 스마트 충분하다. 가서 계획을 비교; 당신은 그들이 동일한있어 볼 수 있습니다. 당신은 당신이 식 평가를 여러 번 볼 더 복잡한 경우가있는 경우 더 복잡한 쿼리 계획을 게시하시기 바랍니다.

    다음은 모두 동일한 실행 계획을 얻을 것이 오 예 쿼리는 다음과 같습니다

    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;
    

    다섯 개 쿼리에 대한 계획을 결과 :

  2. ==============================

    2.당신이 사용하는 크로스 적용 할 수있는

    당신이 사용하는 크로스 적용 할 수있는

    SELECT c.BalanceDue AS BalanceDue
    FROM Invoices
    cross apply (select (InvoiceTotal - PaymentTotal - CreditTotal) as BalanceDue) as c
    WHERE  c.BalanceDue  > 0;
    
  3. ==============================

    3.그것은 효과적으로 선택하고 다른 조항에서 모두 사용할 수있는 변수를 정의 실제로 가능합니다.

    그것은 효과적으로 선택하고 다른 조항에서 모두 사용할 수있는 변수를 정의 실제로 가능합니다.

    및 취급 널 더 투명하게 - 크로스 반드시 적절한 참조 된 테이블의 컬럼에 바인딩을 허용하지 않습니다에 참여하지만 OUTER는 않습니다 적용됩니다.

    SELECT
        vars.BalanceDue
    FROM
        Entity e
    OUTER APPLY (
        SELECT
            -- variables   
            BalanceDue = e.EntityTypeId,
            Variable2 = ...some..long..complex..expression..etc...
        ) vars
    WHERE
        vars.BalanceDue > 0
    

    에드 Mehroz 알람 했네.

  4. from https://stackoverflow.com/questions/11182339/reference-alias-calculated-in-select-in-where-clause by cc-by-sa and MIT license