Chapter 8. Database Queries
TO BE TRANSLATED...
Ein DBMS muss es ermöglichen, die in einer DB gespeicherten Informationen bei Bedarf wieder abzurufen. Dazu werden normalerweise DB-Anfragen formuliert, die ausdrücken, um welche Informationen es geht. In einem RDBMS geht es um Werte für bestimmte Attribute in bestimmten Tabellenzeilen. Diese Werte bilden die Antworten (bzw. die Antwortmenge), die das RDBMS bei der Verarbeitung einer Anfrage erzeugt. Da eine Antwort die Form eines Werte-Tupels hat, entspricht die erzeugte Antwortmenge einer Tabelle.
Um diesen Sachverhalt zu illustrieren, betrachten wir folgende RDB:
books | |||
---|---|---|---|
isbn | title | year | publisher |
006251587X | Weaving the Web | 2000 | Harper Business |
0465026567 | Gödel, Escher, Bach | 1999 | Basic Books |
0465030793 | I Am A Strange Loop | 2000 | Basic Books |
0321312562 | Database Systems | 2005 | Pearson International |
publishers | |
---|---|
name | address |
Basic Books | New York, USA |
Pearson International | London, Great Britain |
Harper Business | New York, USA |
Wenn nach Buchtitel, Verlag und Verlagsadresse aller erfassten Bücher, die im Jahr 2000 erschienen sind, gefragt wird, ergibt sich folgende Antwort-Tabelle:
query results | ||
---|---|---|
title | publisher | address |
I Am A Strange Loop | Basic Books | New York, USA |
Weaving the Web | Harper Business | New York, USA |
Diese Anfrage entspricht folgender SQL-Abfrage:
1 2 3 | SELECT title, publisher, address FROM books, publishers WHERE year = 2000 AND publisher = name |
Diese Abfrage besteht aus drei Schritten:
- sie bildet eine Produktverknüpfung der beiden Tabellen
books
undpublishers
in der FROM-Klausel, - sie selektiert dann durch die WHERE-Klausel diejenigen Zeilen, die die Spaltengleichheitsbedingung
publisher = name
sowie die Spaltenwertbedingungyear = 2000
erfüllen, und - projiziert schließlich durch die SELECT-Klausel die selektierten Zeilen auf die drei Attribute
title
,publisher
,address
.
Die Abfrage wird also mit Hilfe der drei Tabellen-Operationen Produkt, Selektion und Projektion ausgewertet.
Wenn man eine SQL-Abfrage in MS Access eingibt und sie auswerten lässt, kann es sein, dass die Abfrage automatisch umgeschrieben wird. Insbesondere werden Attributnamen um Tabellennamen erweitert (wie z.B. "books.title" statt "title" ) und von Access reservierte Wörter (wie z.B. "Name") werden in eckigen Klammern gesetzt.
Einfache Abfragen
Eine einfache Abfrage setzt sich aus den drei SQL-Klauseln SELECT, FROM und WHERE zusammen, wobei sich die FROM-Klausel nur auf eine Tabelle bezieht, mit SELECT eine Projektion auf eine Teilmenge der Attribute (bzw. Spalten) und mit WHERE eine Selektion der resultierenden Zeilen mit Hilfe von einfachen Zeilenbedingungen vorgenommen wird.
Die allereinfachste Abfrage fragt nach dem Inhalt einer Tabelle, wie z.B.
SELECT * FROM books
query results | |||
---|---|---|---|
isbn | title | year | publisher |
006251587X | Weaving the Web | 2000 | Harper Business |
0465026567 | Gödel, Escher, Bach | 1999 | Basic Books |
0465030793 | I Am A Strange Loop | 2000 | Basic Books |
0321312562 | Database Systems | 2005 | Pearson International |
Hierbei werden in der SELECT-Klausel mit dem Wildcard-Symbol * alle Attribute berücksichtigt. Eine Projektion, also eine Einschränkung auf bestimmte Attribute, wird vermieden. Um das Abfrageresultat auf eine relevante Teilmenge der Attribute einzuschränken, muss in der SELECT-Klausel durch Aufzählung der interessierenden Attribute eine entsprechende Projektion vorgenommen werden, wie z.B. in folgender Abfrage:
SELECT isbn, title FROM books
query results | |
---|---|
isbn | title |
006251587X | Weaving the Web |
0465026567 | Gödel, Escher, Bach |
0465030793 | I Am A Strange Loop |
0321312562 | Database Systems |
Symbolisch kann eine Projektion einer der Tabelle books auf eine Teilmenge [isbn, title] ihrer Spalten folgendermaßen notiert werden:
Um nach bestimmten Büchern zu suchen, muss eine Selektionsbedingung in einer WHERE-Klausel angegeben werden, wie z.B.
SELECT isbn, title FROM books WHERE year = 2000
query results | |
---|---|
isbn | title |
006251587X | Weaving the Web |
0465030793 | I Am A Strange Loop |
Elementare Selektionsbedingungen können nicht nur mit dem Gleicheitsprädikat, sondern auch mit anderen Vergleichsprädikaten (<, >, !=, etc.) sowie mit dem Intervall-Prädikat BETWEEN und dem String-Muster-Prädikat LIKE gebildet werden. Z.B. verlangt die Bedingung price BETWEEN 10 AND 20
, dass der Wert des Attributs price
zwischen 10 und 20 (inklusive) liegt. Die Bedingung title LIKE '%and%'
verlangt, dass der Wert des Attributs title
den Teilstring 'and' enthält. Dabei ist '%' ein Wildcard-Symbol für irgendeinen String (in MS Access wird anstatt dem Symbol '%' das gängugere Wildcard-Symbol '*'.sowie '?' anstatt '_' für ein einzelnes beliebiges Zeichen verwendet).
Symbolisch kann eine Selektion der Tabelle books mit einer Selektionsbedingung year=2000 folgendermaßen notiert werden:
Die Kombination einer Projektion und einer Selektion kann folgendermaßen notiert werden:
Die Zeilen einer Ergebnistabelle können mit einer ORDER-BY-Klausel sortiert werden, wie im nächsten Abfragebeispiel gezeigt wird.
SELECT isbn, title FROM books WHERE year = 2000 ORDER BY title
query results | |
---|---|
isbn | title |
0465030793 | I Am A Strange Loop |
006251587X | Weaving the Web |
Wenn die Sortierung in absteigender Reihenfolge erfolgen soll, ist das Schlüsselwort DESC an die ORDER-BY-Klausel anzuhängen, wie in ORDER BY title DESC
.
Statistische Abfragen
Wir erweitern die oben präsentierte Tabelle books durch Hinzufügung einer Spalte price
für den Buchpreis:
books | ||||
---|---|---|---|---|
isbn | title | year | price | publisher |
006251587X | Weaving the Web | 2000 | 16.00 | Harper Business |
0465026567 | Gödel, Escher, Bach | 1999 | 17.99 | Basic Books |
0465030793 | I Am A Strange Loop | 2000 | 14.99 | Basic Books |
0321312562 | Database Systems | 2005 | 60.00 | Pearson International |
Immer wenn wir derartige Daten haben, kann es sein, dass wir gewisse Statistiken aus ihnen gewinnen wollen:
- Wie viele Bücher gibt es pro Verlag?
- Was ist das Erscheinungsjahr des ältesten Buchs in der Datenbank?
- Was ist der Durchschnittspreis der Bücher des Verlags Basic Books?
Diese drei Beispiele statistischer Anfragen werden in den folgenden SQL-Abfragen ausgedrückt.
SELECT publisher, COUNT(*) AS nmr_of_books FROM books GROUP BY publisher
query results | |
---|---|
publisher | nmr_of_books |
Harper Business | 1 |
Basic Books | 2 |
Pearson International | 1 |
Bei dieser Abfrage werden drei noch nicht behandelte SQL-Elemente verwendet:
- Die COUNT-Aggregatfunktion mit dem Wildcard-Symbol * als Argument bestimmt die Anzahl von Zeilen. Da in dieser Abfrage die Ergebnistabelle gruppiert ist, wird die Zeilenanzahl pro Gruppe ermittelt. Wenn als Argument ein Attribut angegeben ist, wird die Anzahl von Zeilen mit einem Wert für das Attribut (genauer gesagt, mit einem von NULL verschiedenen Attributwert) ermittelt.
- Mit Hilfe von AS kann ein Attribut in der Ergebnistabelle mit einem anderen Spaltentitel ausgegeben oder ein Spaltentitel für einen berechneten Ausdruck definiert werden.
- Die GROUP-BY-Klausel erlaubt es, Zeilen in der Ergebnistabelle nach einem (oder mehreren) Attribut(en) zu gruppieren und für eine Gruppe nur eine Ergebniszeile zu erzeugen. In der SELECT-Klausel einer GROUP-BY-Abfrage können außer Berechnungsausdrücken nur solche Attribute angegeben werden, die auch in der GROUP-BY-Klausel angegeben sind.
Um das Erscheinungsjahr des ältesten Buchs zu ermitteln, kann nach der minimalen Jahreszahl mit Hilfe der Aggregatfunktion MIN gesucht werden:
SELECT MIN(year) AS earliest_year FROM books
query results |
---|
earliest_year |
1999 |
Außer COUNT und MIN gibt es noch folgende Aggregatfunktionen: MAX für maximale Werte, AVG für Durchschnittswerte und SUM für Summenbildung. Beispielsweise kann die Frage "was ist der Durchschnittspreis der Bücher des Verlags Basic Books?" folgendermaßen ausgedrückt werden:
SELECT AVG(price) AS average_price_of_Basic_Books FROM books WHERE publisher = 'Basic Books'
query results |
---|
average_price_of_Basic_Books |
16,49 |
Verschachtelte Abfragen
Eine Abfrage kann anstelle von bestimmten Werten oder Tabellen auch Unterabfragen enthalten, die einen zu berechnenden Wert bzw. eine zu berechnende Tabelle repräsentieren.
Eine Variante der obigen Abfrage nach den Häufigkeiten von publzierten Büchern pro Verlag ergibt sich, wenn die durch COUNT(publisher)
ausgedrückte absolute Häufigkeit durch eine relative Häufigkeit ersetzt wird. Dazu ist die absolute Häufigkeit durch die per SELECT COUNT(*) FROM books
ermittelte Gesamtzahl der Tabellenzeilen zu dividieren. Es wird also ein zu berechnender Wert in einem Spaltenwertausdruck durch eine Unterabfrage ermittelt bzw. repräsentiert., wie in folgendem Beispiel gezeigt wird
SELECT publisher, COUNT(publisher) / (SELECT COUNT(*) FROM books) AS perc_of_books FROM books GROUP BY publisher
query results | |
---|---|
publisher | perc_of_books |
Harper Business | 0.25 |
Basic Books | 0.5 |
Pearson International | 0.25 |
Eine Unterabfrage kann auch in der durch die WHERE-Klausel ausgedrückten Selektionsbedingung vorkommen. Z.B. könnte von den selektierten Zeilen mit Hilfe einer IN-Bedingung verlangt werden, dass ihre Werte für ein Attribut a1
in einer durch eine Unterabfrage berechneten Wertemenge vorkommt:
SELECT * FROM table1 WHERE a1 IN (SELECT a2 FROM table2 WHERE cond2)
Oder es könnte verlangt werden, dass der Wert von a1
kleiner als alle Werte einer Unterabfrage ist, was mit Hilfe von ALL geprüft werden kann:
SELECT * FROM table1 WHERE a1 < ALL (SELECT a2 FROM table2 WHERE cond2)
Auf ähnliche Weise kann mit ANY statt ALL geprüft werden, ob ein Wert kleiner als irgendein Wert einer Unterabfrage ist. Schließlich kann mit Hilfe von EXISTS geprüft werden, ob eine Unterabfrage ein nicht-leeres Resultat hat, es also wenigstens einen Wert bzw. eine Zeile im Resultat gibt.
Abfragen mit mehreren Tabellen
Der Informationsbestand einer Datenbank ist über eine Menge von Tabellen aufgeteilt. Immer wenn bei einer Abfrage Informationen aus mehr als einer Tabelle benötigt werden, müssen diese Tabellen in der Abfrage miteinander verbunden werden. Es gibt verschiedene Tabellen-Verbindungsoperationen. Die wichtigste heißt innerer Verbund (engl. inner join). Alle Verbund-Operationen basieren auf dem Kartesischen Produkt zweier Tabellen, T1 × T2, das wie in der Mengenlehre als Menge aller möglichen Kombinationen definiert ist.
Um ein überschaubares Beispiel für ein Kartesisches Produkt zu erhalten, betrachten wir folgende vereinfachte Bibliotheksdatenbank:
books | ||
---|---|---|
isbn | title | publisher |
006251587X | Weaving the Web | Harper Business |
0465026567 | Gödel, Escher, Bach | Basic Books |
publishers | |
---|---|
name | address |
Basic Books | New York, USA |
Pearson International | London, Great Britain |
Harper Business | New York, USA |
Für diese beiden Tabellen erhalten wir folgendes Kartesische Produkt:
books × publishers | ||||
---|---|---|---|---|
isbn | title | publisher | name | address |
006251587X | Weaving the Web | Harper Business | Basic Books | New York, USA |
006251587X | Weaving the Web | Harper Business | Pearson International | London, Great Britain |
006251587X | Weaving the Web | Harper Business | Harper Business | New York, USA |
0465026567 | Gödel, Escher, Bach | Basic Books | Basic Books | New York, USA |
0465026567 | Gödel, Escher, Bach | Basic Books | Pearson International | London, Great Britain |
0465026567 | Gödel, Escher, Bach | Basic Books | Harper Business | New York, USA |
Dies entspricht folgender SQL-Abfrage:
SELECT * FROM books, publishers
Ein innerer Verbund zweier Tabellen T1 und T2 mit Verbundbedingung C ist eine Selektion des Kartesischen Produkts T1 × T2. Symbolisch:
Ein Beispiel ist der innere Verbund
der es erlaubt, Informationen aus beiden Tabellen (den Buchtitel, den Verlag und seine Adresse) pro Buch wie in Beispiel 8-9 zusammenzuführen.
SELECT title, publisher, address FROM books INNER JOIN publishers ON books.publisher = publishers.name
query results | ||
---|---|---|
title | publisher | address |
Weaving the Web | Harper Business | New York, USA |
Gödel, Escher, Bach | Basic Books | New York, USA |
Alternativ kann eine solche Verbundabfrage auch ohne die Verbundbildung in der FROM-Klausel als Kombination aus Selektion (in der WHERE-Klausel) und Kartesischem Produkt (in der FROM-Klausel) formuliert werden:
SELECT title, publisher, address FROM books, publishers WHERE books.publisher = publishers.name
Wenn man in MS Access Beziehungen zwischen den in einer Abfrage beteiligten Tabellen definiert hat, werden entsprechende Verbund-Abfragen auf der Basis dieser Beziehungen vorgeschlagen.
Vereinigung und Differenz
Während die Verbund-Operation zur Auswertung einer konjunktiven (AND) Anfrage dient, werden zur Auswertung von disjunktiven (OR) bzw. konjunktiv-negierten (AND-NOT) Anfragen die Tabellenoperationen Vereinigung (UNION) und Differenz (EXCEPT) verwendet.
Wir betrachten folgendes DB-Schema:
people = ⟨ id, name⟩
movies = ⟨ id, title, release_date, director⟩
people_as_actors_in_movies = ⟨ person_id, movie_id⟩Zu diesem Schema können wir folgende Abfragen definieren: