it-swarm-eu.dev

Aliasy poddotazů stejné jako aliasy hlavních dotazů

Mám dotaz SQL, jehož aliasy jsou stejné jako některé jeho aliasy jeho poddotazu.

Například:

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

Funguje to dobře, protože alias poddotazu zřejmě skrývá hlavní.

  1. Bude to tak ve všech případech?
  2. Dostanu někdy nedefinované výsledky?
  3. Pokud je to v pořádku, jak mohu učinit odkaz na r hlavního dotazu?
24
IcySnow

Je v pořádku, aby vnořené poddotazy používaly stejné aliasy, jaké byly použity v nadřazeném dotazu, i když to může být pro někoho, kdo čte kód, matoucí. Jmenný prostor pro aliasy vnořeného poddotazu je oddělený od jmenného prostoru nadřazeného. Například dotaz níže obsahuje vnořený poddotaz b, který také obsahuje alias b. To by bylo potenciálně matoucí pro programátora, ale v pořádku s motorem 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

Na korelovaném poddotazu máte přístup k aliasu nadřazeného prvku, takže aliasy musí být jedinečné v nadřazeném dotazu a korelovaném poddotazu. Vezmeme-li korelovaný poddotaz, jako je pod, máme jediný, globální jmenný prostor sdílený mezi nadřazeným dotazem a korelovaným poddotazem:

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)

Korelovaný dílčí dotaz nemá alias, protože se neúčastní spojení jako takového1. Odkazy b a b2 pro bar jsou oba k dispozici pro poddotaz, protože korelované poddotazy sdílejí svůj jmenný prostor pro aliasy s nadřazeným.


1 Všimněte si, že optimalizátor se může rozhodnout použít operátory spojení v rámci plánu v zákulisí, i když skutečnou zadanou operací je korelovaný poddotaz a nikoli spojení proti vnořenému poddotazu.

ConcernedOfTunbridgeWells, píšete (důrazný důl): "Na korelovaný poddotaz máte přístup k aliasu rodičů, takže aliasy musí být jedinečný v nadřazeném dotazu a korelovaném poddotazu. “

Nevěřím, že je vyžadována jedinečnost. Věřím, že pokud se alias použije v korelovaném poddotazu jako název korelace, stejně jako alias tabulky ve vnějším dotazu, bude mít přednost alias v poddotazu.

Příklad:

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)

Výstup je "3": tabulky T a U mají společné 2 a 3, ale predikát WHERE dále filtruje řádky vrácené na 3 a 2 neexistují ve V.

3
slachterman