Programing

WHERE 절의 참조 별명 (SELECT에서 계산 됨)

lottogame 2020. 7. 17. 08:11
반응형

WHERE 절의 참조 별명 (SELECT에서 계산 됨)


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

선택한 열 목록에서 변수로 설정된 계산 된 값 'BalanceDue'는 WHERE 절에서 사용할 수 없습니다.

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


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;

나는 후자를 선호합니다. 표현식이 매우 복잡하거나 계산 비용이 많이 드는 경우, 특히 많은 쿼리가이 동일한 표현식을 참조하는 경우 계산 열 (또는 지속)을 고려해야합니다.

추신 : 당신의 두려움은 근거가없는 것 같습니다. 이 간단한 예에서, SQL Server는 계산을 두 번 참조했지만 계산을 한 번만 수행 할 수있을 정도로 똑똑합니다. 계속해서 계획을 비교하십시오. 당신은 그들이 동일한 것을 볼 수 있습니다. 표현식이 여러 번 평가되는 더 복잡한 경우가있는 경우 더 복잡한 쿼리 및 계획을 게시하십시오.

다음은 모두 정확히 동일한 실행 계획을 생성하는 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;

다섯 가지 쿼리 모두에 대한 결과 계획 :

여기에 이미지 설명을 입력하십시오


당신은 이것을 사용하여 이것을 할 수 있습니다 cross apply

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

실제로 SELECT, WHERE 및 기타 절에서 사용할 수있는 변수를 효과적으로 정의 할 수 있습니다.

교차 조인은 참조 된 테이블 열에 대한 적절한 바인딩을 반드시 허용하지는 않지만 OUTER APPLY는 허용하며 널을보다 투명하게 처리합니다.

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

Syed Mehroz Alam 에게 찬사를 보냅니다 .

참고 URL : https://stackoverflow.com/questions/11182339/reference-alias-calculated-in-select-in-where-clause

반응형