별칭이 하위 쿼리의 별칭과 동일한 SQL 쿼리가 있습니다.
예를 들면 다음과 같습니다.
select *
from ROOM r
where ...
(
select *
from ROAD r
where ...
)
하위 쿼리의 별칭이 기본 별칭을 숨기고있는 것처럼 보이기 때문에 잘 작동합니다.
- 모든 경우에 그렇게 작동합니까?
- 정의되지 않은 결과를 얻을 수 있습니까?
- 그래도 괜찮다면 주 쿼리의 참조를 어떻게 만들 수
r
있습니까?
답변
중첩 된 서브 쿼리가 부모 쿼리에서 사용 된 것과 동일한 별칭을 사용하는 것은 괜찮지 만, 누군가 코드를 읽는 것은 다소 혼란 스러울 수 있습니다. 중첩 된 하위 쿼리의 별칭에 대한 네임 스페이스는 부모의 네임 스페이스와 별개입니다. 예를 들어 아래 쿼리 b
에는 별칭 이있는 중첩 된 하위 쿼리 가 있습니다 b
. 이것은 잠재적으로 프로그래머에게는 혼란 스럽지만 DBMS 엔진에는 문제가 없습니다.
select a.foo
,b.bar
,b.BarCount
from (select b.bar
,count (*) as BarCount
from BarTable b
join OtherTable o
on b.OtherTableID = o.OtherTableID
group by b.bar) b
join Foobar a
on a.bar = b.bar
상관 된 하위 쿼리에서 부모의 별칭에 액세스 할 수 있으므로 별칭은 부모 쿼리 및 상관 된 하위 쿼리에서 고유해야합니다. 아래와 같은 상관 하위 쿼리를 사용하면 상위 쿼리와 상관 하위 쿼리간에 공유되는 단일 전역 네임 스페이스가 있습니다.
select a.foo
,b.bar
from Foobar a
join Bar b
on b.FooBarID = a.FooBarID
where not exists
(select 1
from Bar b2
where b2.BarCategoryID = b.BarCategoryID
and b2.BarDate > b.BarDate)
상관 서브 쿼리는 1 과 같은 조인에 참여하지 않으므로 별명을 갖지 않습니다 . 상관 된 서브 쿼리가 별명에 대한 네임 스페이스를 상위와 공유하므로 서브 쿼리에서 참조 b
및에 b2
대한 정보 bar
를 모두 사용할 수 있습니다.
1 옵티마이 저는 배후의 계획 내에서 조인 연산자를 사용하도록 선택할 수 있지만, 지정된 실제 연산은 상관 된 서브 쿼리이며 중첩 된 서브 쿼리에 대한 조인은 아닙니다.
답변
“별칭이 그래서, 당신은 부모의 별칭에 액세스 할 수 상관 하위 쿼리에 : ConcernedOfTunbridgeWells, 당신은 (강조 광산)를 작성 해야한다 부모 쿼리 및 상관 하위 쿼리에서 고유.”
나는 독창성이 필요하다고 생각하지 않습니다. 외부 쿼리의 테이블 별칭뿐만 아니라 상관 이름으로 상관 하위 쿼리에 별칭이 사용되면 하위 쿼리의 별칭이 우선합니다.
예:
CREATE TABLE #T (A INT)
CREATE TABLE #U (A INT)
CREATE TABLE #V (A INT)
INSERT INTO #T (A) VALUES (1), (2), (3)
INSERT INTO #U (A) VALUES (2), (3), (4)
INSERT INTO #V (A) VALUES (3), (4), (5)
SELECT
T1.A
FROM
#T AS T1
INNER JOIN #U AS T2 ON T1.A = T2.A
WHERE
EXISTS (SELECT * FROM #V AS T2 WHERE T1.A = T2.A)
결과는 “3”입니다. 테이블 T와 U는 공통적으로 2와 3을 갖지만 WHERE
술어는 3으로 리턴 된 행을 추가로 필터링하며 2는 V에 존재하지 않습니다.