Abfragen [basics]: Unterabfragen

Lies diesen Artikel und viele weitere mit einem kostenlosen, einwöchigen Testzugang.

Unterabfragen Was soll das nun wieder sein Ich kenne Unterformulare, aber Unterabfragen Nun: Unterabfragen sind ganz einfach Abfragen, deren Ergebnis als Kriterium in einer übergeordneten Abfrage verwendet wird oder deren Ergebnis als Teil des Ergebnisses der Hauptabfrage ausgegeben werden soll. Dabei gibt es für Unterabfragen spezielle Vorgaben, zum Beispiel dass diese nur ein einziges Feld zurückliefern dürfen (wobei das Feld auch eine Funktion eines Feldes sein kann wie eine Summe oder Anzahl). Wie genau man Unterabfragen definiert und wozu Du diese einsetzen kannst, zeige ich Dir in diesem Artikel.

Beispieldatenbank

Die Beispiele dieses Artikels findest Du in der Datenbank 2301_AbfragenBasics_Unterabfragen.accdb.

Es geht nicht ohne SQL-Ausdrücke

Die schlechte Nachricht vorneweg: Im Gegensatz zu den übrigen Abfragen, die wir in der Abfragen [basics]-Beitragsreihe vorgestellt haben, kommen wir bei Unterabfragen nicht komplett mit dem Zusammenklicken von Abfragen über die Entwurfsansicht aus. Unterabfragen müssen nämlich als SQL-Ausdruck angegeben werden, also zum Beispiel wie folgt:

SELECT KundeID FROM tblKunden

Die gute Nachricht lautet jedoch: In den meisten Fällen können wir diese SELECT-Abfragen zuvor wiederum mit dem Abfrageeditor zusammenstellen und holen uns den benötigten SQL-Ausdruck dann aus der SQL-Ansicht der Abfrage.

SELECT ist Trumpf

Unterabfragen sind immer Auswahlabfragen, die allerdings eine entscheidende Einschränkung aufweisen: Sie enthalten nur ein Ergebnisfeld. Wir können allerdings auf mehrere Tabellen, Kriterien, Gruppierungen und weitere Techniken zurückgreifen.

Wo kann man Unterabfragen einsetzen

Unterabfragen kann man vor allem an zwei Stellen nutzen:

  • in Ausdrücken, also in berechneten Feldern
  • in Kriterien von Abfragefeldern

Unterabfrage als Ausdruck

In einem berechneten Feld kann man das Ergebnis einer beliebigen Unterabfrage entweder als alleinigen Wert oder als Teil eines Ausdrucks mit anderen Informationen ausgeben. Wir könnten beispielsweise die Anzahl der Artikel der Tabelle in der gleichen Zeile mit den Daten des Artikels ausgeben. Das sieht zum Beispiel wie im Screenshot aus Bild 1 aus. Hier fügen wir also die folgende Abfrage als Unterabfrage hinzu:

Beispiel einer Unterabfrage zur Ermittlung der Artikelanzahl

Bild 1: Beispiel einer Unterabfrage zur Ermittlung der Artikelanzahl

SELECT Count(*) FROM tblArtikel

Damit diese ihre Werte auch in dem von uns hinzugefügten Feld anzeigt, müssen wir einen Feldnamen für dieses berechnete Feld hinterlegen, in diesem Fall AnzahlArtikel. Außerdem ist es zwingend erforderlich, dass wir die Unterabfrage in Klammern einfassen, sodass dieser Ausdruck zum Einsatz kommt:

AnzahlArtikel: (SELECT Count(*) FROM tblArtikel)

Wechseln wir in die Datenblattansicht, erhalten wir das Ergebnis aus Bild 2. Auf die gleiche Weise können wir auch Daten aus anderen Tabellen anzeigen.

Die Anzahl der Artikel erscheint in jeder Zeile.

Bild 2: Die Anzahl der Artikel erscheint in jeder Zeile.

Unterabfrage als Ausdruck mit Bezug zur Hauptabfrage

Das war ein sehr einfaches Beispiel, das kaum praktischen Nutzen hat. Was eher vorkommen könnte, wäre der Wunsch nach der Anzeige der Anzahl der Artikel der Kategorie des aktuellen Artikels. Sprich: Dies Hauptabfrage zeigt weiterhin alle Artikel der Tabelle tblArtikel an. In der Unterabfrage wollen wir die Anzahl der Artikel ermitteln, die der Kategorie angehören, zu welcher der aktuelle Artikel der Hauptabfrage gehört. Dazu müssen wir nun in der Unterabfrage ein Kriterium hinzufügen, dass sich auf die Kategorie-ID des Artikels aus der Hauptabfrage bezieht.

Das ist nicht ganz so einfach, denn wie sollen wir bei der Formulierung des Kriteriums in der Unterabfrage das Feld KategorieID der Hauptabfrage mit dem gleichnamigen Feld der Unterabfrage vergleichen – wenn beide sich auf die gleiche Tabelle beziehen Auch zu diesem Zweck gibt es in relationalen Datenbanken die Möglichkeit, einer Tabelle einen Aliasnamen zu geben. Wir legen also entweder in der Haupt- oder in der Unterabfrage fest, dass die Tabelle tblArtikel unter einem anderen Namen angesprochen werden soll, beispielsweise t1. Wir könnten auch für beide Instanzen der Tabelle tblArtikel in der Datenbank einen Aliasnamen vergeben, beispielsweise t1 für die Tabelle in der Hauptabfrage und t2, damit es richtig klar wird.

Um für die Tabelle tblArtikel in der Hauptabfrage einen Aliasnamen festzulegen, aktivieren wir das Eigenschaftenblatt für diese Tabelle und legen den Aliasnamen für die Eigenschaft Alias fest (siehe Bild 3).

Festlegen eines Aliasnamens für eine Tabelle einer Abfrage

Bild 3: Festlegen eines Aliasnamens für eine Tabelle einer Abfrage

Allerdings erscheint nun überall in der Abfrage t1 statt tblArtikel, was bei Verwendung mehrerer Tabellen in der Abfrage nicht zur Übersicht beiträgt (siehe Bild 4).

Tabelle mit Aliasname in einer Abfrage

Bild 4: Tabelle mit Aliasname in einer Abfrage

Daher würden wir in diesem Fall eher der Tabelle in der Unterabfrage den Aliasnamen t1 zuweisen (zuvor ersetzen wir den Aliasnamen der Tabelle in der Hauptabfrage allerdings wieder durch den eigentlichen Namen der Tabelle, also tblArtikel). Um einer Tabelle im SQL-Code, den wir für Unterabfragen angeben müssen, mit einem Aliasnamen zu versehen, geben wir hinter dem Tabellennamen im FROM-Bereich das AS-Schlüsselwort gefolgt vom Aliasnamen an:

SELECT Count(*) FROM tblArtikel AS t1 

Dieser brauchen wir nun nur noch das Kriterium zuzuweisen, in dem wir die KategorieID der Tabelle der Unterabfrage mit der der Tabelle in der Hauptabfrage abgleichen:

SELECT Count(*) FROM tblArtikel AS t1 WHERE t1.KategorieID = tblArtikel.KategorieID

Diese Unterabfrage soll also die Anzahl der Datensätze aus der Tabelle tblArtikel holen, deren KategorieID mit der KategorieID des aktuellen Datensatzes in der Abfrage entspricht. Dazu fassen wir die Unterabfrage noch in Klammern ein und stellen dieser den Namen des berechneten Feldes voran. Der Abfrageentwurf sieht anschließend wie in Bild 5 aus.

Ermitteln der Anzahl der Artikel der Kategorie des aktuellen Artikels

Bild 5: Ermitteln der Anzahl der Artikel der Kategorie des aktuellen Artikels

Wechseln wir jetzt in die Datenblattansicht, erscheint zu jedem Artikel die Anzahl der Artikel der gleichen Kategorie (siehe Bild 6).

Anzahl der Artikel der Kategorie des aktuellen Artikels

Bild 6: Anzahl der Artikel der Kategorie des aktuellen Artikels

Anzahl verknüpfter Datensätze

Im nächsten Beispiel wollen wir herausfinden, wie viele verknüpfte Datensätze es für die Datensätze der zu untersuchenden Tabelle gibt. Im konkreten Fall interessiert uns die Anzahl der Bestellungen eines jeden Kunden, die wir als zusätzliches Feld des Abfrageergebnisses ausgeben wollen. Dazu nutzen wir eine Abfrage, die in der Hauptabfrage Daten der Tabelle tblKunden anzeigt und in einem berechneten Feld namens AnzahlBestellungen die Anzahl der Datensätze der Tabelle tblBestellungen, die mit dem aktuellen Kundendatensatz verknüpft sind. Die dazu benötigte Unterabfrage enthält wieder eine Bedingung, welche ein Feld der Tabelle der Unterabfrage mit einem Feld der Tabelle der Hauptabfrage abgleicht. Diesmal handelt es sich allerdings um unterschiedliche Tabellen, daher brauchen wir keinen Aliasnamen zu definieren. Der Entwurf der Unterabfrage ist in zu Bild 7 finden.

Entwurf der Abfrage zur Ermittlung der Anzahl der Bestellungen eines Kunden

Bild 7: Entwurf der Abfrage zur Ermittlung der Anzahl der Bestellungen eines Kunden

Wechseln wir in die Datenblattansicht, liefert die Abfrage alle Kunden mit der Anzahl ihrer Bestellungen (siehe Bild 8).

Ausgabe der Anzahl der Bestellungen je Kunde

Bild 8: Ausgabe der Anzahl der Bestellungen je Kunde

Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...

Testzugang

eine Woche kostenlosen Zugriff auf diesen und mehr als 1.000 weitere Artikel

diesen und alle anderen Artikel mit dem Jahresabo

  1. Moin. Vielen Dank für diesen Artikel!
    Gibt es einen eleganten SQL-Weg, in dem Beispiel “Bestimmte Menge Datensätze einer Gruppe” die Top3-Einträge nicht als 3 Datensätze sondern als einen Datensatz zurück zu geben, zum Beispiel als verkettete, kommagetrennte Strings? Also, zum Beispiel
    Kategorie | Artikel
    Gewürze | Vegie-spread, Cranberry Sauce, Sirop
    Süßwaren | Marmelade, Tarte, Schokolade
    In Power Query ist das sehr einfach zu lösen. In SQL bastel ich mir hierfür recht umständlich Abfragen zusammen (einzelne Abfrage für jede Top1Artikel-Position, Top2Artikel-Position, Top3Artikel-Position einer Kategorie, diese dann in einer Hauptabfrage mit der Kategorien-Tabelle verknüpfen, Top1, Top2 Top3 als einzelne Felder ausgeben und diese dann verknüpfen).

Schreibe einen Kommentar