기본 쿼리의 별칭과 동일한 하위 쿼리의 별칭


23

별칭이 하위 쿼리의 별칭과 동일한 SQL 쿼리가 있습니다.

예를 들면 다음과 같습니다.

select *
from ROOM r
where ...
         (
              select *
              from ROAD r
              where ...
         )

하위 쿼리의 별칭이 기본 별칭을 숨기고있는 것처럼 보이기 때문에 잘 작동합니다.

  1. 모든 경우에 그렇게 작동합니까?
  2. 정의되지 않은 결과를 얻을 수 있습니까?
  3. 그래도 괜찮다면 주 쿼리의 참조를 어떻게 만들 수 r있습니까?

1
짧은 답변은 "1. 예", "2. 아니오"및 "3.이 경우에는 할 수 없습니다 (따라서 참조를 원한다면 실제로는 좋지 않습니다)"
ypercubeᵀᴹ

답변:


15

중첩 된 서브 쿼리가 부모 쿼리에서 사용 된 것과 동일한 별칭을 사용하는 것은 괜찮지 만, 누군가 코드를 읽는 것은 다소 혼란 스러울 수 있습니다. 중첩 된 하위 쿼리의 별칭에 대한 네임 스페이스는 부모의 네임 스페이스와 별개입니다. 예를 들어 아래 쿼리 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 옵티마이 저는 배후의 계획 내에서 조인 연산자를 사용하도록 선택할 수 있지만, 지정된 실제 연산은 상관 된 서브 쿼리이며 중첩 된 서브 쿼리에 대한 조인은 아닙니다.


첫 번째 쿼리의 하위 쿼리는 파생 테이블이며 표준 SQL에는 항상 이름을 지정해야합니다.이 요구 사항에 대한 논리적 인 이유는 없지만 SQL Server는이를 구현했습니다. 특정 예에서는 이름을 선택했습니다. 필요합니다. 두 번째 쿼리의 하위 쿼리는 파생 테이블이 아니므로 이름이 필요하지 않은 이유 ( 상관 된 하위 쿼리 라는 사실 이 중요하지 않음).
1

@onedaywhen-하위 쿼리가 부모에서 사용되는 별칭에 액세스 해야하는 상관 하위 쿼리는 생각할 수 없습니다. 특정한 것을 염두에 두셨습니까?
ConcernedOfTunbridgeWells

귀하의 질문을 이해하지 못했습니다. 아마도 "상관 된 하위 쿼리에는 조인에 참여하지 않기 때문에 별칭이 없습니다."라는 의견에 구체적으로 응답하고 있음을 분명히해야합니다. 내 대답은 범위 변수에 관한 규칙 (SQL 표준이 '상관 이름'이라고 부르고 '별칭'이라고 부르는 것)이 조인 참여 또는 직접 참여와 직접 관련이 없다는 점을 전달해야했습니다.
1

간단한 예 : SELECT * FROM ( SELECT c FROM T ) AS T2;-조인, 상관 관계 없음 SQL 표준에서는 파생 테이블에 범위 변수 ( T2이 경우)를 할당해야합니다 .
1

3

"별칭이 그래서, 당신은 부모의 별칭에 액세스 할 수 상관 하위 쿼리에 : 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에 존재하지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.