it-swarm.com.de

Aliase für Unterabfragen wie Aliase für Hauptabfragen

Ich habe eine SQL-Abfrage, deren Aliase mit einigen Aliasnamen der Unterabfrage identisch sind.

Zum Beispiel:

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

Dies funktioniert gut, da der Alias ​​der Unterabfrage den Hauptalias zu verbergen scheint.

  1. Wird es in allen Fällen so funktionieren?
  2. Werde ich jemals undefinierte Ergebnisse erhalten?
  3. Wenn dies in Ordnung ist, wie kann ich auf das r der Hauptabfrage verweisen?
24
IcySnow

Für verschachtelte Unterabfragen ist es in Ordnung, dieselben Aliase wie in der übergeordneten Abfrage zu verwenden, obwohl dies für jemanden, der den Code liest, etwas verwirrend sein kann. Der Namensraum für Aliase in einer verschachtelten Unterabfrage ist vom Namensraum auf der übergeordneten Unterabfrage getrennt. In der folgenden Abfrage ist beispielsweise eine verschachtelte Unterabfrage b enthalten, in der auch ein Alias ​​b verwendet wird. Dies wäre für den Programmierer möglicherweise verwirrend, für die DBMS-Engine jedoch in Ordnung:

   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

Bei einer korrelierten Unterabfrage haben Sie Zugriff auf die Aliase des übergeordneten Elements. Daher müssen die Aliase für die übergeordnete Abfrage und die korrelierte Unterabfrage eindeutig sein. Wenn wir eine korrelierte Unterabfrage wie die folgende verwenden, haben wir einen einzelnen globalen Namensraum, der zwischen der übergeordneten Abfrage und der korrelierten Unterabfrage geteilt wird:

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)

Die korrelierte Unterabfrage hat keinen Alias, da sie nicht an einem Join als solchem ​​teilnimmt1. Die Referenzen b und b2 für bar stehen der Unterabfrage beide zur Verfügung, da korrelierte Unterabfragen ihren Namespace für Aliase mit dem übergeordneten Element teilen.


1 Beachten Sie, dass der Optimierer möglicherweise Verknüpfungsoperatoren innerhalb des Plans hinter den Kulissen verwendet, obwohl die tatsächlich angegebene Operation eine korrelierte Unterabfrage und keine Verknüpfung mit einer verschachtelten Unterabfrage ist.

ConcernedOfTunbridgeWells schreiben Sie (Hervorhebung von mir): "Bei einer korrelierten Unterabfrage haben Sie Zugriff auf die Aliase der Eltern, also auf die Aliase muss in der übergeordneten Abfrage und der korrelierten Unterabfrage eindeutig sein. "

Ich glaube nicht, dass Einzigartigkeit erforderlich ist. Ich glaube, wenn ein Alias ​​in einer korrelierten Unterabfrage als Korrelationsname sowie ein Tabellenalias in der äußeren Abfrage verwendet wird, hat der Alias ​​in der Unterabfrage Vorrang.

Beispiel:

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)

Die Ausgabe ist "3": Die Tabellen T und U haben 2 und 3 gemeinsam, aber das Prädikat WHERE filtert die auf 3 zurückgegebenen Zeilen weiter, und 2 existiert in V nicht.

3
slachterman