web-dev-qa-db-ja.com

サブクエリのエイリアスはメインクエリのエイリアスと同じ

エイリアスがサブクエリのエイリアスの一部と同じであるSQLクエリがあります。

例えば:

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

サブクエリのエイリアスがメインのエイリアスを隠しているように見えるため、これは正常に機能します。

  1. それはすべての場合にそのように機能しますか?
  2. 未定義の結果が得られることはありますか?
  3. それが問題ない場合、どうすればメインクエリのrを参照できますか?
24
IcySnow

ネストされたサブクエリが親クエリで使用されているのと同じエイリアスを使用することは問題ありませんが、コードを読む人にとっては少し混乱するかもしれません。ネストされたサブクエリのエイリアスの名前空間は、親の名前空間とは異なります。たとえば、以下のクエリには、ネストされたサブクエリ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 for 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に存在しません。

3
slachterman