WHERE 절의 참조 별칭(SELECT로 계산됨)
SELECT (InvoiceTotal - PaymentTotal - CreditTotal) AS BalanceDue
FROM Invoices
WHERE BalanceDue > 0 --error
계산된 값BalanceDue
선택한 열 목록에서 변수로 설정된 것은WHERE
절을 클릭합니다.
할 수 있는 방법이 있을까요?이 관련 질문(Where Clause의 MySQL Select Statement 변수 사용)에서는 실제로는 계산을 두 번(및 쿼리에서 해당 계산을 수행)만 하면 되는 것처럼 보이지만, 어느 것도 만족스럽지 않습니다.
SELECT는 평가되는 두 번째 마지막 절이기 때문에 ORDER BY를 제외하고 별칭을 참조할 수 없습니다.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는 두 번 참조하더라도 계산을 한 번만 수행할 수 있을 정도로 스마트합니다.어서 설계도를 비교해 보세요. 그것들이 똑같다는 것을 알게 될 거예요.표현이 여러 번 평가되는 더 복잡한 케이스가 있는 경우, 더 복잡한 쿼리와 계획을 게시해 주십시오.
다음은 모두 동일한 실행 계획을 생성하는 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가지 쿼리 모두에 대한 결과 계획:
다음을 사용하여 이 작업을 수행할 수 있습니다.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에서는 null을 보다 투명하게 처리합니다.
SELECT
vars.BalanceDue
FROM
Entity e
OUTER APPLY (
SELECT
-- variables
BalanceDue = e.EntityTypeId,
Variable2 = ...some..long..complex..expression..etc...
) vars
WHERE
vars.BalanceDue > 0
시드 메흐로즈 알람에게 경의를 표합니다.
WHERE 구 앞에 SELECT 구를 강제로 평가하기 위한 회피책으로 서브쿼리가 메인쿼리에 남아 있는 동안 서브쿼리를 서브쿼리에 넣을 수 있습니다.
SELECT * FROM (
SELECT (InvoiceTotal - PaymentTotal - CreditTotal) AS BalanceDue
FROM Invoices) AS temp
WHERE BalanceDue > 0
심플한 어프로치
SELECT * FROM Invoices GROUP BY id
HAVING(InvoiceTotal - PaymentTotal - CreditTotal) > 0
언급URL : https://stackoverflow.com/questions/11182339/reference-alias-calculated-in-select-in-where-clause
'UFO ET IT' 카테고리의 다른 글
변수가 Bash의 숫자인지 테스트하려면 어떻게 해야 합니까? (0) | 2023.04.08 |
---|---|
여러 파일의 확장자 이름을 변경하려면 어떻게 해야 합니까? (0) | 2023.04.08 |
테이블 명명 딜레마:단수 vs여러 이름 (0) | 2023.04.08 |
배치 파일 실행 후 콘솔 자동 닫힘 방지 방법 (0) | 2023.04.08 |
배치 파일의 앳 기호(@)는 무엇이며 어떤 역할을 합니까? (0) | 2023.04.08 |