Korrelierte Unterabfragen in Invantive UniversalSQL

Eine Unterabfrage kann nun eine Spalte aus der umgebenden Abfrage verwenden.

Damit steht eine übliche Methode zur Verfügung, um „die Zeile, die zu dieser Zeile gehört“ in Invantive UniversalSQL zu beschreiben, wie im untenstehenden Beispiel gezeigt. Bisher führte eine solche Unterabfrage zu einer Meldung, dass die Spalte unbekannt war.

Funktionsweise

Eine Unterabfrage sucht einen Namen zunächst in ihren eigenen Datenquellen. Erst wenn sie den Namen dort nicht kennt, schaut sie in die umgebende Abfrage und danach in die Abfrage, die diese wiederum umgibt. Ein Name, der an beiden Stellen existiert, verweist also auf den nächstgelegenen. Das Hinzufügen einer Spalte zu einer Tabelle kann daher nicht die Bedeutung einer bestehenden Unterabfrage verändern.

Eine Korrelation darf auf beliebig viele Ebenen nach außen greifen und kann eine Ebene überspringen. Eine Unterabfrage, die zwei Ebenen tief liegt, kann eine Spalte aus der äußeren Abfrage verwenden, ohne dass die dazwischenliegende Abfrage eine Rolle spielt.

Die Korrelation ist in denselben Formen erlaubt wie eine Unterabfrage ohne Korrelation: exists und not exists, in und not in, sowie die skalare Unterabfrage. Letztere liefert einen Wert und darf überall dort stehen, wo ein Ausdruck erlaubt ist, also auch in der Auswahlliste, in einer Berechnung und in einem case.

Beispiel: Existiert eine Zugehörige Zeile

Das folgende Beispiel wählt die Mitarbeiter aus, deren Abteilung in der zweiten Datensammlung vorkommt. Die Unterabfrage verwendet emp.dept, eine Spalte der umgebenden Abfrage:

select emp.code
from   ( select 'A100' code, 'SLS' dept
         union all
         select 'A200' code, 'ENG' dept
       ) emp
where  exists ( select 1
                from   ( select 'SLS' dept
                       ) dpt
                where  dpt.dept = emp.dept
              )

Dies liefert eine Zeile mit dem Wert A100. Mitarbeiter A200 arbeitet in einer Abteilung, die in der zweiten Sammlung nicht bekannt ist.

Beispiel: Ein Wert Pro Zeile

Eine skalare Unterabfrage in der Auswahlliste zählt die Zeilen, die zu jedem Mitarbeiter gehören:

select emp.code
,      ( select count(*)
         from   ( select 'A100' code
                  union all
                  select 'A100' code
                ) ord
         where  ord.code = emp.code
       ) orders
from   ( select 'A100' code
         union all
         select 'A200' code
       ) emp

Dies liefert A100 mit 2 und A200 mit 0. Eine count über keine zugehörigen Zeilen ergibt Null. Jede andere Aggregation, wie max oder sum, liefert in dieser Situation den leeren Wert.

Leere Werte

Ein Vergleich mit dem leeren Wert hat kein Ergebnis, und dieses Ergebnis variiert je nach Form. Bei exists ist eine Zeile, die mit dem leeren Wert verglichen wird, kein Treffer, sodass die Unterabfrage nichts findet. Bei not in macht ein leerer Wert zwischen den gelieferten Werten die Antwort unentschieden, wodurch die Zeile nicht geliefert wird. Das gilt auch, wenn der verglichene Wert selbst leer ist.

Anzahl der Anfragen an die Plattform

Eine korrelierte Unterabfrage wird vor der Ausführung in einen Join umgeschrieben. Jede Datenquelle wird dadurch unabhängig von der Anzahl der Zeilen der umgebenden Abfrage eine feste Anzahl von Malen gelesen.

Ohne diese Umschreibung würde die Unterabfrage einmal pro Zeile ausgeführt, was auf einer Plattform, die über die Cloud angesprochen wird, 1 Anfrage pro Zeile bedeutet.

Einschränkung

Eine Unterabfrage in einem order by wird noch nicht unterstützt.

Verfügbarkeit

Korrelierte Unterabfragen sind ab der Version 27.0 für alle Plattformen verfügbar.

Siehe auch