태그 보관물: sql-server

sql-server

기본 쿼리의 별칭과 동일한 하위 쿼리의 별칭 SQL 쿼리가 있습니다. 예를 들면 다음과 같습니다. select

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

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

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

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

  1. 모든 경우에 그렇게 작동합니까?
  2. 정의되지 않은 결과를 얻을 수 있습니까?
  3. 그래도 괜찮다면 주 쿼리의 참조를 어떻게 만들 수 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에 존재하지 않습니다.


답변