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


22

エイリアスがそのサブクエリのエイリアスのいくつかと同じであるSQLクエリがあります。

例えば:

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

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

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

1
簡単な答えは「1.はい」、「2。いいえ」、「3。その場合はできません(そのような参照を作成したい場合は本当に大丈夫ではありません)」
ypercubeᵀᴹ12年

回答:


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およびb2for barは、サブクエリで使用できます。相関サブクエリは、エイリアスの名前空間を親と共有するためです。


1オプティマイザーは、背後で計画内で結合演算子を使用することを選択できることに注意してください。ただし、指定された実際の操作は相関サブクエリであり、ネストされたサブクエリに対する結合ではありません。


最初のクエリのサブクエリは派生テーブルであり、標準SQLでは常に名前を付ける必要があります。この要件には論理的な理由はありませんが、SQL Serverはそれを実装していますが、特定の例では名前を選択しています必須。2番目のクエリのサブクエリは派生テーブルではないため、名前を必要としない理由です(相関サブクエリであるという事実は重要ではありません)。
いつか

@onedaywhen-サブクエリが親で使用されるエイリアスにアクセスする必要がある相関サブクエリ以外の状況は考えられません。特定の何かを念頭に置いていましたか?
ConcernedOfTunbridgeWells

私はあなたの質問を理解できません。「相関サブクエリにはエイリアスはありません。それ自体は結合に参加しないので」というコメントに具体的に応答していることを明確にする必要があります。私の応答は、範囲変数に関する規則(SQL標準で「相関名」と呼ばれ、「エイリアス」と呼ばれるもの)が結合への参加(またはその他)に直接関係しないという点を伝えることになっています。
いつか

簡単な例:SELECT * FROM ( SELECT c FROM T ) AS T2;-結合も相関もまだありませんSQL標準では、派生テーブルに範囲変数(T2この場合)を割り当てる必要があります。
いつか

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に返される行をさらにフィルタリングし、Vには2は存在しません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.