요약
할 수 없었던 논리적 인 이유 는 없지만, 이점은 적으며 즉시 명백하지 않을 수있는 함정이 있습니다.
연구 결과
나는 약간의 연구를하고 좋은 정보를 찾았다. 다음은 2012-08-09 17:49 GMT의 신뢰할 수있는 기본 소스 (익명으로 유지하려는)의 직접적인 인용입니다.
SQL이 처음 발명되었을 때 SELECT 절에 별칭이 없었습니다. 이것은 1986 년에 ANSI에 의해 언어가 표준화 될 때 수정 된 심각한 단점이었습니다.
이 언어는 "비 절차 적", 즉 언어를 찾는 방법을 지정하지 않고 원하는 데이터를 설명하기위한 것입니다. 따라서 내가 아는 한 SQL 구현이 쿼리를 처리하기 전에 전체 쿼리를 구문 분석 할 수없는 이유는 없으며 어디에서나 별칭을 정의하고 사용할 수 있습니다. 예를 들어 다음 쿼리가 유효하지 않은 이유는 없습니다.
select name, salary + bonus as pay
from employee
where pay > 100000
이것이 합리적인 쿼리라고 생각하지만 일부 SQL 기반 시스템은 구현 관련 이유로 별칭 사용에 대한 제한을 도입 할 수 있습니다. SQL Server가이 작업을 수행한다고 들었습니다.
SQL-86 표준에 대한 추가 연구와 최신 DBMS가 별칭 재사용을 지원하지 않는 이유에 관심이 있지만 아직까지는 아직 멀지 않았습니다. 우선, 문서를 어디서 구할 수 있는지 또는 누가위원회를 정확하게 구성했는지 알아낼 수 없습니다. 누구든지 도울 수 있습니까? 또한 SQL Server의 원래 Sybase 제품에 대해 더 알고 싶습니다.
이 연구와 몇 가지 추가 생각을 통해 다른 절에서 별칭을 사용하면 다른 언어 기능에 비해 DBMS 제조업체의 우선 순위가 결코 높지 않은 것으로 의심됩니다. 쿼리 작성자가 쉽게 해결할 수있는 것은 그리 큰 장애물이 아니기 때문에 다른 발전에 노력을 기울이는 것은 최적이 아닙니다. 또한 분명히 SQL 표준의 일부가 아니기 때문에 독점적 일 것입니다 (확실히 더 기다리고 있습니다). 그러나 약간 개선되어 DBMS 간의 SQL 호환성이 손상되었습니다. 비교하면 CROSS APPLY
(실제로 외부 참조를 허용하는 파생 테이블에 지나지 않습니다.) 큰 변화이지만 독점은 다른 방식으로는 쉽게 수행 할 수없는 놀라운 표현력을 제공합니다.
어디서나 별칭을 사용할 때의 문제
SELECT 항목을 WHERE 절에 넣을 수 있으면 쿼리의 복잡성 (따라서 우수한 실행 계획을 찾는 복잡성)을 폭발적으로 확장 할 수있을뿐만 아니라 완전히 비논리적 인 것들을 생각 해낼 수 있습니다. 시험:
SELECT X + 5 Y FROM MyTable WHERE Y = X
MyTable에 이미 열 Y가있는 경우, 어느 것이 WHERE 절을 참조합니까? 해결책은 CTE 또는 파생 테이블을 사용하는 것입니다. 대부분의 경우 추가 비용이 들지 않지만 동일한 최종 결과를 얻을 수 있습니다. CTE와 파생 테이블은 별칭을 한 번만 사용할 수 있도록하여 모호성을 해결합니다.
또한 FROM 절에서 별명을 사용하지 않으면 의미가 있습니다. 당신은 이것을 할 수 없습니다 :
SELECT
T3.ID + (SELECT Min(Interval) FROM Intervals WHERE IntName = 'T') CalcID
FROM
Table1 T
INNER JOIN Table2 T2
ON T2.ID = CalcID
INNER JOIN Table3 T3
ON T2.ID = T3.ID
즉, (T2 비밀리 그 테이블은 가입리스트에 제시되기 전에, T3의 값을 참조하고있는 점에서), 원형의 기준 터무니 보이지. 이건 어때:
INSERT dbo.FinalTransaction
SELECT
newid() FinalTransactionGUID,
'GUID is: ' + Convert(varchar(50), FinalTransactionGUID) TextGUID,
T.*
FROM
dbo.MyTable T
newid () 함수가 실행 계획에 두 번 배치되어 두 열이 완전히 다른 값을 표시하게 만드는 데 얼마나 걸립니까? 위의 쿼리가 CTE 또는 파생 테이블에서 N 수준 깊이 사용되는 경우는 어떻습니까? 나는 당신이 상상할 수있는 것보다 문제가 더 나쁘다는 것을 보증한다. 쿼리 계획에서 상황이 한 번만 평가되는 시점이나 시점에 대해 불일치 문제 가 이미 발생했으며 Microsoft는 이를 해결하지 않을 것이라고 말했습니다.쿼리 대수를 올바르게 표현하기 때문에 일부는 예상치 못한 결과가 나오면 쿼리를 여러 부분으로 나눕니다. 체인 참조를 허용하고 잠재적으로 매우 긴 체인을 통해 순환 참조를 감지하는 것은 상당히 까다로운 문제입니다. 병렬 처리를 도입하면 제작에 악몽이 생깁니다.
참고 : WHERE 또는 GROUP BY에서 별칭을 사용해도 newid () 또는 rand ()와 같은 함수의 문제와 차이가 없습니다.
재사용 가능한 표현식을 작성하는 SQL Server 방법
CROSS APPLY / OUTER APPLY는 SQL Server에서 쿼리의 다른 곳에서 사용할 수있는 식을 만드는 한 가지 방법입니다 (FROM 절의 초반이 아님).
SELECT
X.CalcID
FROM
Table1 T
INNER JOIN Table3 T3
ON T.ID = T3.ID
CROSS APPLY (
SELECT
T3.ID + (SELECT Min(Interval) FROM Intervals WHERE IntName = 'T') CalcID
) X
INNER JOIN Table2 T2
ON T2.ID = X.CalcID
이것은 두 가지 일을합니다.
- CROSS APPLY의 모든 표현식이 "네임 스페이스"(여기서는 X)를 가져오고 해당 네임 스페이스 내에서 고유하게합니다.
- CalcID가 X에서 나올뿐 아니라 X가 아직 소개되지 않았기 때문에 테이블 T1과 T3을 조인 할 때 X에서 어떤 것도 사용할 수없는 이유를 분명히 알 수 있습니다.
나는 실제로 CROSS APPLY를 좋아합니다. 그것은 나의 충실한 친구가되었고, 나는 그것을 항상 사용합니다. 부분 UNPIVOT (기본 구문을 사용하는 PIVOT / UNPIVOT 또는 UNPIVOT / PIVOT이 필요함)이 필요합니까? CROSS APPLY로 완료했습니다. 여러 번 재사용 할 계산 된 값이 필요하십니까? 끝난. 연결된 서버를 통한 통화에 대한 실행 순서를 엄격하게 시행해야합니까? 속도가 크게 향상되었습니다. 한 가지 유형의 행만 2 행으로 분할하거나 추가 조건이 필요합니까? 끝난.
따라서 DBMS SQL Server 2005 이상에서는 최소한 더 이상 불만을 제기 할 필요가 없습니다. CROSS APPLY는 원하는 방식으로 건조하는 방법입니다.