SQL-Abfragen: Unterschied zwischen den Versionen

Aus IV1
Zeile 47: Zeile 47:
# NOT AND OR
# NOT AND OR


Die folgende Anweisung gibt die Spalten ''Vorname'' und ''Nachname'' all jener Datensätze in der Tabelle ''Kunde'' aus, die im Feld ''Vorname'' "Michael" entsprechen.
<pre>SELECT Vorname, Nachname
<pre>SELECT Vorname, Nachname
FROM Kunde
FROM Kunde
WHERE Vorname='Michael'</pre>
WHERE Vorname='Michael'</pre>
(gibt die Spalten ''Vorname'' und ''Nachname'' all jener Datensätze in der Tabelle ''Kunde'' aus, die im Feld ''Vorname'' "Michael" entsprechen)
<form method="post" action="http://sql.idv.edu/thema/work/sql.php" target="_blank">
<form method="post" action="http://sql.idv.edu/thema/work/sql.php" target="_blank">
<input type="hidden" name="select5a" value="SELECT Vorname, Nachname FROM Kunde WHERE Vorname='Michael'"><br />
<input type="hidden" name="select5a" value="SELECT Vorname, Nachname FROM Kunde WHERE Vorname='Michael'"><br />
Zeile 57: Zeile 57:
Bei Zeit/Zahlenwerten als Bedingung ist nicht nur das "="-Zeichen erlaubt sondern auch <, >, <>, >= und <=. Im Gegensatz zu Textwerten müssen diese dann auch nicht in einfache Anführungszeichen gesetzt werden.
Bei Zeit/Zahlenwerten als Bedingung ist nicht nur das "="-Zeichen erlaubt sondern auch <, >, <>, >= und <=. Im Gegensatz zu Textwerten müssen diese dann auch nicht in einfache Anführungszeichen gesetzt werden.


Das Auswahlverfahren könnte nun mithilfe von Boolschen Operatoren (AND, OR, NOT, usw...) verfeinert werden.
Das Auswahlverfahren könnte nun mithilfe von Boolschen Operatoren (AND, OR, NOT, usw...) verfeinert werden. Die Abfrage unterhalb gibt die Spalten ''Vorname'', ''Nachname'' und ''Plz'' der Datensätze in der Tabelle ''Kunde'' aus, die im Feld ''Vorname'' "Michael" entsprechen und eine ''Plz'' kleiner 4030 besitzen.
<pre>SELECT Vorname, Nachname, Plz
<pre>SELECT Vorname, Nachname, Plz
FROM Kunde
FROM Kunde
WHERE Vorname='Michael' AND Plz<4030</pre>
WHERE Vorname='Michael' AND Plz<4030</pre>
(gibt die Spalten ''Vorname'', ''Nachname'' und ''Plz'' der Datensätze in der Tabelle ''Kunde'' aus, die im Feld ''Vorname'' "Michael" entsprechen und eine ''Plz'' kleiner 4030 besitzen)
<form method="post" action="http://sql.idv.edu/thema/work/sql.php" target="_blank">
<form method="post" action="http://sql.idv.edu/thema/work/sql.php" target="_blank">
<input type="hidden" name="select6a" value="SELECT Vorname, Nachname, Plz FROM Kunde WHERE Vorname='Michael' AND Plz<4030"><br />
<input type="hidden" name="select6a" value="SELECT Vorname, Nachname, Plz FROM Kunde WHERE Vorname='Michael' AND Plz<4030"><br />
<input type="submit" name="select6b" value="Ausführen"></form>
<input type="submit" name="select6b" value="Ausführen"></form>


Diese Abfrage gibt die Spalten ''Vorname'', ''Nachname'' und ''Plz'' jeder Zeile der Tabelle ''Kunde'' aus, die eine ''Plz'' zwischen 1010 und 4030 besitzt.
<pre>SELECT Vorname, Nachname, Plz
<pre>SELECT Vorname, Nachname, Plz
FROM Kunde
FROM Kunde
WHERE Plz BETWEEN 1010 AND 4030</pre>
WHERE Plz BETWEEN 1010 AND 4030</pre>
(gibt die Spalten ''Vorname'', ''Nachname'' und ''Plz'' jeder Zeile der Tabelle ''Kunde'' aus, die eine ''Plz'' zwischen 1010 und 4030 besitzt)
<form method="post" action="http://sql.idv.edu/thema/work/sql.php" target="_blank">
<form method="post" action="http://sql.idv.edu/thema/work/sql.php" target="_blank">
<input type="hidden" name="select7a" value="SELECT Vorname, Nachname, Plz FROM Kunde WHERE Plz BETWEEN 1010 AND 4030"><br />
<input type="hidden" name="select7a" value="SELECT Vorname, Nachname, Plz FROM Kunde WHERE Plz BETWEEN 1010 AND 4030"><br />
<input type="submit" name="select7b" value="Ausführen"></form>
<input type="submit" name="select7b" value="Ausführen"></form>


Ist nur ein Teil des Suchbegriffs innerhalb eines Feldes bekannt, so kann nach diesen Schlüsselwörtern gesucht werden. Das "%"-Zeichen dient als Platzhalter, welcher beliebige (und beliebig viele) Zeichen davor bzw. danach zulässt.
Ist nur ein Teil des Suchbegriffs innerhalb eines Feldes bekannt, so kann nach diesen Schlüsselwörtern gesucht werden. Das "%"-Zeichen dient als Platzhalter, welcher beliebige (und beliebig viele) Zeichen davor bzw. danach zulässt. Folglich gibt die nächste Abfrage die Spalten ''Vorname'' und ''Nachname'' der Datensätze in der Tabelle ''Kunde'' aus,  die im Feld Nachname "Muster" an beliebiger Stelle enthalten.
<pre>SELECT Vorname, Nachname
<pre>SELECT Vorname, Nachname
FROM Kunde
FROM Kunde
WHERE Nachname LIKE '%Muster%'</pre>
WHERE Nachname LIKE '%Muster%'</pre>
(gibt die Spalten ''Vorname'' und ''Nachname'' der Datensätze in der Tabelle ''Kunde'' aus,  die im Feld Nachname "Muster" an beliebiger Stelle enthalten)
<form method="post" action="http://sql.idv.edu/thema/work/sql.php" target="_blank">
<form method="post" action="http://sql.idv.edu/thema/work/sql.php" target="_blank">
<input type="hidden" name="select8a" value="SELECT Vorname, Nachname FROM Kunde WHERE Nachname LIKE '%Muster%'"><br />
<input type="hidden" name="select8a" value="SELECT Vorname, Nachname FROM Kunde WHERE Nachname LIKE '%Muster%'"><br />

Version vom 2. März 2009, 14:55 Uhr

Die SELECT Anweisung

Eine SQL-Datenbank kann mit der SELECT-Anweisung abgefragt werden, wenn die entsprechenden Zugriffsrechte vorliegen. Nachfolgende Beispiele beziehen sich auf die Implementierung des bei den Normalformen dargestellten Modells in einem SQL-Trainingsserver, welche als interpretierende Maschine unter http://sql.idv.edu erreichbar ist. Die Zugriffsrechte auf die Lehr- und Übungsdatenbank erlauben lediglich die Anwendungen von Abfragen mit der SELECT-Anweisung. Um das Antwortzeitverhalten besonders in Prüfungszeiten zu verbessern, wurde die Ausgabe der Treffer auf 500 Datensätze begrenzt.

Ausgeben von Datensätzen

Mit dem SELECT-Schlüsselwort lassen sich bestimmte Datensätze aus einer Datenbank auslesen, die dann später anderwärtig (z.B. durch eine Script- oder Programiersprache) weiterverarbeitet werden. Als Beispieltabelle kommt hier die Tabelle Kunde (und später auch die Tabelle PLZ) aus der Buchhandlungs-Datenbank zum Einsatz.

Eine Liste aller Vornamen aus der Tabelle Kunde kann noch über einen sehr einfachen Befehl erstellt werden.

SELECT Vorname
FROM Kunde

<form method="post" action="http://sql.idv.edu/thema/work/sql.php" target="_blank"> <input type="hidden" name="select1a" value="SELECT Vorname FROM Kunde">
<input type="submit" name="select1b" value="Ausführen"></form>

Um mehrere Spalten auflisten zu lassen, müssen diese (mit Komma getrennt) in der Abfrage angegeben werden. Folgend werden nur die Spalten Vorname, Nachname und Plz aller Datensätze der Tabelle Kunde ausgegeben.

SELECT Vorname, Nachname, Plz
FROM Kunde

<form method="post" action="http://sql.idv.edu/thema/work/sql.php" target="_blank"> <input type="hidden" name="select2a" value="SELECT Vorname, Nachname, Plz FROM Kunde">
<input type="submit" name="select2b" value="Ausführen"></form>

Oft ist aber unbekannt, wie alle Felder in einer Tabelle heißen. In so einem Fall, oder um einfach alle Felder in die Abfrage einzubeziehen, kann man anstatt der Spalten einfach den sogenannten Joker (das Multiplikationszeichen "*") einsetzen.

SELECT *
FROM Kunde

<form method="post" action="http://sql.idv.edu/thema/work/sql.php" target="_blank"> <input type="hidden" name="select" value="SELECT * FROM Kunde">
<input type="submit" value="Ausführen"></form>

Ausschließen von Wiederholungen

Öfters kommt es nun vor, dass Inhalte gewisser Spalten mehrfach in den Datensätzen vorkommen. Soll z.B. eine Liste aller Nachnamen erstellt werden, so könnte es durchaus passieren, dass mehrere Personen in der Tabelle den selben Nachnamen haben. Damit jeder Nachname aber wirklich nur einmal vorkommt wird der Term DISTINCT hinter SELECT gestellt.

SELECT DISTINCT Nachname
FROM Kunde

<form method="post" action="http://sql.idv.edu/thema/work/sql.php" target="_blank"> <input type="hidden" name="select4a" value="SELECT DISTINCT Nachname FROM Kunde">
<input type="submit" name="select4b" value="Ausführen"></form>

Auswählen von Datensätzen

Um bestimmte Zeilen (Datensätze) einer Tabelle auszuwählen, muss angegeben werden, welche Bedingung für diese Zeilen gelten soll. Die Bedingungen werden in der WHERE-Komponente definiert. Sie enthalten Operatoren, für die nachfolgende Reihenfolge anzuwenden ist.

  1. ( )
  2. * /
  3. + -
  4. = <> > <
  5. NOT AND OR

Die folgende Anweisung gibt die Spalten Vorname und Nachname all jener Datensätze in der Tabelle Kunde aus, die im Feld Vorname "Michael" entsprechen.

SELECT Vorname, Nachname
FROM Kunde
WHERE Vorname='Michael'

<form method="post" action="http://sql.idv.edu/thema/work/sql.php" target="_blank"> <input type="hidden" name="select5a" value="SELECT Vorname, Nachname FROM Kunde WHERE Vorname='Michael'">
<input type="submit" name="select5b" value="Ausführen"></form>

Bei Zeit/Zahlenwerten als Bedingung ist nicht nur das "="-Zeichen erlaubt sondern auch <, >, <>, >= und <=. Im Gegensatz zu Textwerten müssen diese dann auch nicht in einfache Anführungszeichen gesetzt werden.

Das Auswahlverfahren könnte nun mithilfe von Boolschen Operatoren (AND, OR, NOT, usw...) verfeinert werden. Die Abfrage unterhalb gibt die Spalten Vorname, Nachname und Plz der Datensätze in der Tabelle Kunde aus, die im Feld Vorname "Michael" entsprechen und eine Plz kleiner 4030 besitzen.

SELECT Vorname, Nachname, Plz
FROM Kunde
WHERE Vorname='Michael' AND Plz<4030

<form method="post" action="http://sql.idv.edu/thema/work/sql.php" target="_blank"> <input type="hidden" name="select6a" value="SELECT Vorname, Nachname, Plz FROM Kunde WHERE Vorname='Michael' AND Plz<4030">
<input type="submit" name="select6b" value="Ausführen"></form>

Diese Abfrage gibt die Spalten Vorname, Nachname und Plz jeder Zeile der Tabelle Kunde aus, die eine Plz zwischen 1010 und 4030 besitzt.

SELECT Vorname, Nachname, Plz
FROM Kunde
WHERE Plz BETWEEN 1010 AND 4030

<form method="post" action="http://sql.idv.edu/thema/work/sql.php" target="_blank"> <input type="hidden" name="select7a" value="SELECT Vorname, Nachname, Plz FROM Kunde WHERE Plz BETWEEN 1010 AND 4030">
<input type="submit" name="select7b" value="Ausführen"></form>

Ist nur ein Teil des Suchbegriffs innerhalb eines Feldes bekannt, so kann nach diesen Schlüsselwörtern gesucht werden. Das "%"-Zeichen dient als Platzhalter, welcher beliebige (und beliebig viele) Zeichen davor bzw. danach zulässt. Folglich gibt die nächste Abfrage die Spalten Vorname und Nachname der Datensätze in der Tabelle Kunde aus, die im Feld Nachname "Muster" an beliebiger Stelle enthalten.

SELECT Vorname, Nachname
FROM Kunde
WHERE Nachname LIKE '%Muster%'

<form method="post" action="http://sql.idv.edu/thema/work/sql.php" target="_blank"> <input type="hidden" name="select8a" value="SELECT Vorname, Nachname FROM Kunde WHERE Nachname LIKE '%Muster%'">
<input type="submit" name="select8b" value="Ausführen"></form>

Sortieren von Datensätzen

Selbstverständlich können die auszugebenden Datensätze im Ergebnis auch nach bestimmten Kriterien gereiht werden. Diese Sortierung geschieht durch den Zusatz ORDER BY, gefolgt von den Feldern, nach denen sortiert werden soll. Weiters kann noch bestimmt werden, ob dies aufsteigend (ASC) oder absteigend (DESC) geschehen soll.

SELECT Vorname, Nachname
FROM Kunde
ORDER BY Nachname, Vorname ASC

(gibt die Spalten Vorname und Nachname jeder Zeile in der Tabelle Kunde aus, aufsteigend sortiert anhand der Spalten Nachname und Vorname) <form method="post" action="http://sql.idv.edu/thema/work/sql.php" target="_blank"> <input type="hidden" name="select9a" value="SELECT Vorname, Nachname FROM Kunde ORDER BY Nachname, Vorname ASC">
<input type="submit" name="select9b" value="Ausführen"></form>

Gruppieren von Datensätzen

Die GROUP BY-Klausel bewirkt, dass die aus einer Abfrage resultierende Tabelle in Gruppen gegliedert wird. Dazu muss in der GROUP BY-Klausel angegeben werden, nach welchem Kriterium die Gruppierung erfolgen soll. Dieses Kriterium, der Gruppierungsschlüssel, ist im einfachsten Fall ein Attribut der Ausgangstabelle. Alle Zeilen mit demselben Wert des Gruppierungsschlüssels fallen in dieselbe Gruppe. Eine Gruppe ist also nichts anderes als eine Teiltabelle. Im Ergebnis wird jede Gruppe durch die Anwendung von Gruppierungsfunktionen auf eine einzelne Zeile zusammengefasst.

Als typische Gruppenfunktionen gelten:

  • COUNT
  • SUM
  • AVG
  • MAX
  • MIN

Die Gruppenfunktionen werden analog zu gängigen Funktionen in Tabellenkalkulationsprogrammen angewandt und notiert, z.B. SUM(Auftragspos.Menge * Buch.Preis).

SELECT Region, COUNT(*)
FROM PLZ
WHERE Ort LIKE '%kirche%'
GROUP BY Region
ORDER BY 2 DESC

(gibt das gruppierte Feld Region und die Anzahl der Orte, die "kirche" enthalten, aus der Tabelle PLZ aus, absteigend sortiert anhand der zweiten Spalte) <form method="post" action="http://sql.idv.edu/thema/work/sql.php" target="_blank"> <input type="hidden" name="select10a" value="SELECT Region, COUNT(*) FROM PLZ WHERE Ort LIKE '%kirche%' GROUP BY Region ORDER BY 2 DESC">
<input type="submit" name="select10b" value="Ausführen"></form>

Mit der Gruppenfunktion generierte Spalten können mit AS benannt und dadurch auch für weitere Aktionen (z.B. ORDER BY) innerhalb der selben Abfrage verwendet werden. Die folgende Abfrage stellt bereits eine eher komplexe Abfrage mit einigen Joins dar.

SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz
FROM PLZ, Kunde, Auftrag, Auftragspos, Buch
WHERE PLZ.Plz=Kunde.Plz
AND Kunde.Nr=Auftrag.Kundennummer
AND Auftrag.Nr=Auftragspos.Auftragsnummer
AND Auftragspos.Buchnummer=Buch.Nr
GROUP BY Kunde.Nr
ORDER BY Kunde.Nachname

(gibt die Spalten Kunde.Nr, Kunde.Nachname, PLZ.Ort und den errechneten Umsatz aus den Tabellen PLZ, Kunde, Auftrag, Auftragspos und Buch aus, gruppiert das Ergebnis nach der Kundennummer und sortiert es am Nachnamen) <form method="post" action="http://sql.idv.edu/thema/work/sql.php" target="_blank"> <input type="hidden" name="select11a" value="SELECT Kunde.Nr, Kunde.Nachname, PLZ.Ort, SUM(Auftragspos.Menge*Buch.Preis) AS Umsatz FROM PLZ, Kunde, Auftrag, Auftragspos, Buch WHERE PLZ.Plz=Kunde.Plz AND Kunde.Nr=Auftrag.Kundennummer AND Auftrag.Nr=Auftragspos.Auftragsnummer AND Auftragspos.Buchnummer=Buch.Nr GROUP BY Kunde.Nr ORDER BY Kunde.Nachname">
<input type="submit" name="select11b" value="Ausführen"></form>

Verbinden von Tabellen

Zur Unterstützung zahlreicher Aufgaben aus dem betrieblichen Alltag werden Daten benötigt, die über mehrere Tabellen hinweg verteilt sind. Das Zusammenführen von Feldern aus mehreren Tabellen heißt auch Join und wird ebenfalls in der WHERE Komponente definiert.

Bei Abfragen, die über mehrere Tabellen gehen, ist es ratsam, die Feldnamen in Verbindung mit dem Tabellennamen anzuführen. Aus Vorname wird Kunde.Vorname. Diese Maßnahme ist dann notwendig, wenn in ein und derselben Abfrage idente Feldbezeichnungen auftauchen. Die Kunde.Nr muss z.B. von der Artikel.Nr und diese von der Buch.Nr unterschieden werden können.

Die Verbindung der benötigten Tabellen erfolgt über die Schlüsselfelder. In der Regel wird ein Primärschlüssel einer Tabelle mit einem Fremdschlüssel einer weiteren Tabelle verbunden. Dazu ist es hilfreich, das normalisierte Datenmodell zu verwenden. Die gerichteten Kanten weisen den Weg der Verbindungen (Joins).

SELECT Tabelle1.Feld1, Tabelle2.Feld1, Tabelle2.Feld2
FROM Tabelle1, Tabelle2
WHERE (Tabelle1.Feld2=Tabelle2.Feld2)

Diese Art der Abfrage wird dazu verwendet, um Daten aus zwei verschiedenen Tabellen zu einem Datensatz zu kombinieren. Somit wird das WHERE hier nicht mehr zur Selektion verwendet (so wie in den vorangegangenen Beispielen), sondern zur Projektion von Daten. Sobald also mit einer etwas komplexeren Datenbank mit mehreren verbundenen Tabellen gearbeitet wird, ergibt sich die Notwendigkeit, auf diese Art und Weise an die benötigten Daten zu kommen.

Für das Beispiel wir nun eine zweite Tabelle (die Tabelle PLZ) benötigt. Die Informationen, die zu einer Postleitzahl gehören, wurden in diese ausgelagert. Die beiden Tabellen PLZ und Kunde sind über das Feld Plz verbunden. Achtung: Bei diesem Beispiel darf man sich nicht verwirren lassen, dass der Tabellenname PLZ genauso lautet wie das Feld Plz!

SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Plz, PLZ.Ort
FROM Kunde, PLZ
WHERE (Kunde.Plz=PLZ.Plz)

(gibt je Datensatz die Spalten Vorname, Nachname und Plz aus der Tabelle Kunde sowie das jeweils entsprechende Feld Ort aus der Tabelle PLZ aus) <form method="post" action="http://sql.idv.edu/thema/work/sql.php" target="_blank"> <input type="hidden" name="select12a" value="SELECT Kunde.Vorname, Kunde.Nachname, Kunde.Plz, PLZ.Ort FROM Kunde, PLZ WHERE (Kunde.Plz=PLZ.Plz)">
<input type="submit" name="select12b" value="Ausführen"></form>