SQL - Structured Query Language Wozu dienen SQL-Befehle? Eine häufige Anwendung ist die Auswahl von Daten aus den Tabellen einer Datenbank. Und damit kommen wir schon zu zwei Schlüsselwörtern: wir wählen (SELECT) Daten aus (FROM) einer Tabelle. Was ist eine relationale Datenbank? Eine Tabelle ist ein Container in der Datenbank, der die Daten enthält. Die Tabellen sind i.a. untereinander durch ein System von sogenannten Schlüsseln verknüpft. Die Verknüpfungen (Beziehungen) und die Attribute (Spalten der Tabellen) werden durch das Datenbankdesign festgelegt. Begiffe im Bereich DBSY Relation ....... Tabelle Tupel .......... Zeile Attribut ....... Spaltenbezeichner Entität ........ Eintrag in einem Tabellenfeld (Datum) Das Entity Relationship Modell (Diagramm) Mittels ER-Diagramm (Entity Relationship Diagram) wird eine relationale Datenbank modelliert. Man unterscheidet hier den Entitätstyp – also die Zusammenfassung von Entitäten gleicher Eigenschaft - und die Attribute, die die Eigenschaften von Entitäten beschreiben. Entitäten können in Beziehung zueinander gesetzt werden - z.B. „Kunde kauft Produkt“. Beziehungen 1:1, 1:n und n:m HINWEIS: n:m-Beziehungen müssen i.a. durch eine Zwischentabelle, bestehend aus den Primärschlüsseln der n- und m-Tabellen, in Relationen 1:n und 1:m aufgelöst werden. Beziehungen in UML 0..1 optional eindeutig 0..* optional mehrdeutig 1..1 obligatorisch eindeutig 1..* obligatorisch mehrdeutig ER-Diagramme findet man oft in UML-Notation. Interessant ist, dass das ER-Diagramm in UML mit Hilfe des Klassentyps dargestellt wird. Der Klassenbezeichner ist der Name der Relation (Tabelle) und die Methoden sind die Attribute (Spaltenbezeichner), jeweils mit einem „+“-Zeichen vorangestellt. Die Beziehungen sind mit Linien dargestellt, deren Endpunkte mit den Beziehungsbezeichnern, wie oben dargestellt (z.B. 0..*) versehen sind. SQL – Kommandos und Syntax SQL unterscheidet zwei Kategorien von Kommandos: DML und DDL. DML … Manipulation Language … z.B. SELECT, INSERT … DDL … Definition Language … z.B. CREATE, ALTER 1. Select SELECT "Spalten_Name" FROM "Tabellen_Name" Gehen wir zur Verdeutlichung des obigen Beispiels von folgender Tabelle aus: Tabelle Store_Information store_name Sales Los Angeles 1500€ San Diego 250€ Los Angeles 300€ Date 05.Jan.1999 07.Jan.1999 08.Jan.1999 Boston 700€ 08.Jan.1999 Das ist d ie Beispieltabelle für das gesamte Tutorial. Um alle Warenhäuser in dieser Tabelle auszuwählen, geben wir ein: SELECT store_name FROM Store_Information Ausgabe: store_name Los Angeles San Diego Los Angeles Boston Es lassen sich sowohl mehrere Spaltennamen als auch mehrere Tabellennamen auswählen. 2. Distinct Mit dem Schlüsselwort SELECT lässt sich der gesamte Inhalt einer Tabellenspalte (oder mehrerer Spalten) auswählen. Dies bedeutet natürlich, dass es auch Redundanzen geben kann. Nehmen wir aber an, wir möchten nur alle unterschiedlichen (DISTINCT) Elemente auswählen. Dies ist in SQL sehr einfach. Wir müssen dazu lediglich DISTINCT nach SELECT hinzufügen. Die Syntax sieht folgendermaßen aus: SELECT DISTINCT "Spalten_Name" FROM "Tabellen_Name" Um zum Beispiel alle unterschiedlichen Warenhäuser in der Tabelle Store_Information auszuwählen, Tabelle Store_Information store_name Sales Los Angeles 1500€ San Diego 250€ Los Angeles 300€ Boston 700€ Date 05.Jan.1999 07.Jan.1999 08.Jan.1999 08.Jan.1999 geben wir ein: SELECT DISTINCT store_name FROM Store_Information Ausgabe: store_name Los Angeles San Diego Boston 3. Where Nehmen wir an, wir möchten nur Daten aus einer Tabelle auswählen, die bestimmte Bedingungen erfüllen. Zum Beispiel nur Warenhäuser mit einem Umsatz von mehr als 1.000 €. Dazu verwenden wir das Schlüsselwort WHERE. Die Syntax sieht folgendermaßen aus: SELECT "Spalten_Name" FROM "Tabellen_Name" WHERE "Bedingung" Um zum Beispiel alle Warenhäuser mit einem Umsatz von mehr als 1.000 € in der Tabelle Store_Information auszuwählen, Tabelle Store_Information store_name Sales Los Angeles 1500€ San Diego 250€ Los Angeles 300€ Boston 700€ geben wir ein: SELECT store_name FROM Store_Information WHERE Sales > 1000 Date 05.Jan.1999 07.Jan.1999 08.Jan.1999 08.Jan.1999 Ausgabe: store_name Los Angeles 4. AND / OR Im vorhergehenden Abschnitt haben wir das Schlüsselwort WHERE kennen gelernt, mit dem sich Daten aus einer Tabelle auswählen lassen, die bestimmte Bedingungen erfüllen. Dabei kann es sich um eine einfache Bedingung (wie im vorigen Beispiel) oder eine zusammengesetzte Bedingung handeln. Zusammengesetzte Bedingungen bestehen aus mehreren durch AND oder OR verbundenen einfachen Bedingungen. Eine einzelne SQL-Anweisung kann eine unbegrenzte Anzahl einfacher Bedingungen enthalten. Die Syntax für eine zusammengesetzte Bedingung sieht folgendermaßen aus: SELECT "Spalten_Name" FROM "Tabellen_Name" WHERE "einfache Bedingung" {[AND|OR] "einfache Bedingung"}+ Das Symbol {}+ bedeutet, dass der Ausdruck in der Klammer einmal oder mehrere Male auftreten kann. Beachten Sie, dass AND und OR austauschbar verwendet werden können. Zusätzlich kann mit dem Klammersymbol () die Reihenfolge der Bedingung angegeben werden. So könnten wir zum Beispiel alle Warenhäuser mit einem Umsatz von mehr als 1.000 € oder alle Warenhäuser mit einem Umsatz von weniger als 500 €, aber mehr als 275 € in der Tabelle Store_Information auswählen. Tabelle Store_Information store_name Sales Los Angeles 1500€ San Diego 250€ Date 05.Jan.1999 07.Jan.1999 San Francisco Boston 300€ 700€ 08.Jan.1999 08.Jan.1999 geben wir ein: SELECT store_name FROM Store_Information WHERE Sales > 1000 OR (Sales < 500 AND Sales > 275) Ausgabe: store_name Los Angeles San Francisco 5. IN In SQL gibt es zwei Verwendungen für das Schlüsselwort IN, wobei der vorliegende Abschnitt sich auf diejenige im Zusammenhang mit der WHERE-Klausel bezieht. Bei einer Verwendung in diesem Zusammenhang ist für mindestens eine der Spalten bekannt, welche Werte genau ausgegeben werden sollen. Die Syntax für das Schlüsselwort IN sieht folgendermaßen aus: SELECT "Spalten_Name" FROM "Tabellen_Name" WHERE "Spalten_Name" IN ('Wert1', 'Wert2', ...) Die Klammer kann einen Wert oder mehrere durch Kommas getrennte Werte enthalten. Die Werte können mit Zahlen oder Buchstaben ausgedrückt werden. Befindet sich nur ein Wert in der Klammer, entspricht dieser Befehl WHERE "Spalten_Name" = 'Wert1' Wir könnten zum Beispiel alle Datensätze für die Warenhäuser Los Angeles und San Diego in der Tabelle Store_Information auswählen. Tabelle Store_Information store_name Sales Los Angeles 1500€ San Diego 250€ San Francisco 300€ Boston 700€ Date 05.Jan.1999 07.Jan.1999 08.Jan.1999 08.Jan.1999 geben wir ein: SELECT * FROM Store_Information WHERE store_name IN ('Los Angeles', 'San Diego') Ausgabe: store_name Los Angeles San Diego Sales 1500€ 250€ Date 05.Jan.1999 07.Jan.1999 6. Between (mySQL) Während mit dem Schlüsselwort IN die Auswahlkriterien auf einen oder mehrere diskrete Werte begrenzt werden können, erlaubt BETWEEN die Auswahl eines Bereichs. Die Syntax für die BETWEEN-Klausel sieht folgendermaßen aus: SELECT "Spalten_Name" FROM "Tabellen_Name" WHERE "Spalten_Name" BETWEEN 'Wert1' AND 'Wert2' Dadurch werden alle Zeilen ausgewählt, deren Spalte einen Wert zwischen 'Wert1' und 'Wert2' hat. So könnten wir zum Beispiel alle Umsatzdaten zwischen dem 6. Januar 1999 und dem 10. Januar 1999 in der Tabelle Store_Information auswählen, um diese anzeigen zu lassen. Tabelle Store_Information store_name Sales Los Angeles 1500€ San Diego 250€ San Francisco 300€ Boston 700€ Date 05.Jan.1999 07.Jan.1999 08.Jan.1999 08.Jan.1999 geben wir ein: SELECT * FROM Store_Information WHERE Date BETWEEN '06.Jan.1999' AND '10.Jan.1999' Beachten Sie bitte, dass das Datum je nach Datenbank in verschiedenen Formaten gespeichert werden kann. In diesem Tutorial beschränken wir uns der Einfachheit halber auf eins der Formate. Ausgabe: store_name San Diego San Francisco Boston Sales 250€ Date 07.Jan.1999 300€ 08.Jan.1999 700€ 08.Jan.1999 7. Like LIKE ist ein weiteres Schlüsselwort, das in der WHERE-Klausel Verwendung findet. Im Wesentlichen ermöglicht LIKE eine Suche auf der Grundlage eines Musters an Stelle einer genauen Angabe (wie bei IN) oder der Definition eines Bereichs (wie bei BETWEEN). Die Syntax sieht folgendermaßen aus: SELECT "Spalten_Name" FROM "Tabellen_Name" WHERE "Spalten_Name" LIKE {MUSTER} (In Access: * statt % und “ statt ‘) {MUSTER} besteht oft aus Platzhaltern. Hier einige Beispiele: 'A_Z': Alle Zeichenketten die mit einem 'A' beginnen, worauf ein weiteres Zeichen folgt, und mit einem 'Z' enden. 'ABZ' und 'A2Z' würden beispielsweise diese Bedingung erfüllen, 'AKKZ' hingegen nicht (wegen der zwei Zeichen zwischen A und Z). 'ABC%': Alle Zeichenketten, die mit 'ABC' beginnen. Sowohl 'ABCD' als auch 'ABCABC' würden zum Beispiel diese Bedingung erfüllen. '%XYZ': Alle Zeichenketten, die auf 'XYZ' enden. So würden beispielsweise sowohl 'WXYZ' als auch 'ZZXYZ' diese Bedingung erfüllen. '%AN%': Alle Zeichenketten, die an irgendeiner Stelle das Muster 'AN' enthalten. Sowohl 'LOS ANGELES' als auch 'SAN FRANCISCO' würden zum Beispiel diese Bedingung erfüllen. Gehen wir von folgender Tabelle aus: Tabelle Store_Information store_name Sales LOS ANGELES 1500€ SAN DIEGO 250€ SAN FRANCISCO 300€ BOSTON 700€ Date 05.Jan.1999 07.Jan.1999 08.Jan.1999 08.Jan.1999 Wir möchten nun alle Warenhäuser finden, deren Name 'AN' enthält. Wir geben ein: SELECT * FROM Store_Information WHERE store_name LIKE '%AN%' Ausgabe: store_name LOS ANGELES SAN DIEGO Sales 1500€ 250€ 8. SAN FRANCISCO Date 05.Jan.1999 07.Jan.1999 300€ 08.Jan.1999Order By Bisher haben wir uns mit dem Abrufen von Daten aus einer Tabelle unter Verwendung der Befehle SELECT und WHERE beschäftigt. In vielen Fällen müssen die ausgegebenen Daten jedoch auf eine bestimmte Weise sortiert werden. Dies könnte beispielsweise in aufsteigender oder absteigender Reihenfolge oder auf der Grundlage eines Zahlenwerts oder Textwerts geschehen. In solchen Fällen können wir das Schlüsselwort ORDER BY einsetzen. Die Syntax für eine ORDER BY-Anweisung sieht folgendermaßen aus: SELECT "Spalten_Name" FROM "Tabellen_Name" [WHERE "Bedingung"] ORDER BY "Spalten_Name" [ASC | DESC] Das Symbol [] bedeutet, dass die WHERE-Anweisung optional ist. Ist jedoch eine WHERE-Klausel vorhanden, steht sie vor der ORDER BY-Klausel. ASC bedeutet, dass die Ergebnisse in aufsteigender Reihenfolge angezeigt werden, DESC, dass sie in absteigender Reihenfolge erscheinen. Findet sich keine diesbezügliche Angabe, wird die Voreinstellung ASC verwendet. Es besteht die Möglichkeit, nach mehr als einer Spalte zu sortieren. In diesem Fall sieht die ORDER BY-Klausel wie folgt aus: ORDER BY "Spalten_Name1" [ASC | DESC], "Spalten_Name2" [ASC | DESC] Wenn wir beispielsweise für beide Spalten eine aufsteigende Sortierung wählen, erfolgt die Ausgabe in aufsteigender Reihenfolge gemäß Spalte 1. Liegt eine Verknüpfung für den Wert von Spalte 1 vor, erfolgt die Sortierung in aufsteigender Reihenfolge nach Spalte 2. So könnten wir zum Beispiel den Inhalt der Tabelle Store_Information nach Euro-Beträgen in absteigender Reihenfolge sortieren: Tabelle Store_Information store_name Sales Los Angeles 1500€ San Diego 250€ San Francisco 300€ Boston 700€ Date 05.Jan.1999 07.Jan.1999 08.Jan.1999 08.Jan.1999 geben wir ein: SELECT store_name, Sales, Date FROM Store_Information ORDER BY Sales DESC Ausgabe: store_name Sales Los Angeles Boston San Francisco San Diego 1500€ 700€ 300€ 250€ Date 05.Jan.1999 08.Jan.1999 08.Jan.1999 07.Jan.1999 Zusätzlich zum Spaltennamen lässt sich auch mit der Spaltenposition (basierend auf der SQLAbfrage) angeben, auf welche Spalte die ORDER BY-Klausel bezogen werden soll. Die erste Spalte ist 1, die zweite 2 usw. Im obigen Beispiel werden die gleichen Ergebnisse mit folgendem Befehl erreicht: SELECT store_name, Sales, Date FROM Store_Information ORDER BY 2 DESC 9. Aggregatfunktionen von SQL Da wir uns hier bereits mit Zahlen beschäftigt haben, liegt natürlich die Frage nahe, ob mir mit diesen Zahlen Rechenoperationen wie Addition oder Mittelwertbildung durchführen können. Die Antwort lautet ja! SQL verfügt über mehrere arithmetische Funktionen, und zwar: AVG, COUNT, MAX, MIN, SUM Die Syntax für die Funktionen sieht folgendermaßen aus: SELECT "Funktionstyp"("Spalten_Name") FROM "Tabellen_Name" Um zum Beispiel die Summe aller Umsatzerlöse aus der folgenden Tabelle zu erhalten, Tabelle Store_Information store_name Sales Los Angeles 1500€ San Diego 250€ Los Angeles 300€ Boston 700€ Date 05.Jan.1999 07.Jan.1999 08.Jan.1999 08.Jan.1999 geben wir ein: SELECT SUM(Sales) FROM Store_Information Ausgabe: SUM(Sales) 2750€ 2750€ entspricht der Summe aller Umsatzeinträge: 1500€ + 250€ + 300€ + 700€. Zusätzlich zu diesen Funktionen können mit SQL auch einfache Aufgaben wie Addition (+) und Subtraktion (-) durchgeführt werden. Für Zeichendaten stehen auch einige Zeichenkettenfunktionen zur Verfügung, wie Verkettungs-, Trim- und Teilstring-Funktionen. Die einzelnen Anbieter relationaler Datenbank-Managementsysteme verwenden teilweise verschiedene Implementierungen von Zeichenkettenfunktionen. Es empfiehlt sich daher, in den entsprechenden Unterlagen nachzulesen, wie diese Funktionen jeweils eingesetzt werden. 10. Count Eine weitere arithmetische Funktion ist mit COUNT verfügbar. Sie erlaubt die Zählung (COUNT) der Zeilen in einer bestimmten Tabelle. Die Syntax lautet: SELECT COUNT("Spalten_Name") FROM "Tabellen_Name" Wir wollen zum Beispiel die Anzahl der Warenhauseinträge in unserer Tabelle ermitteln. Tabelle Store_Information store_name Sales Los Angeles 1500€ San Diego 250€ Los Angeles 300€ Boston 700€ Date 05.Jan.1999 07.Jan.1999 08.Jan.1999 08.Jan.1999 wir geben ein: SELECT COUNT(store_name) FROM Store_Information Ausgabe: Count(store_name) 4 COUNT und DISTINCT können zusammen in einer Anweisung verwendet werden, um die Anzahl der individuellen Einträge in einer Tabelle auszulesen. Um zum Beispiel die Anzahl unterschiedlicher Warenhäuser herauszufinden, würden wir eingeben: SELECT COUNT(DISTINCT store_name) FROM Store_Information Ausgabe: Count(DISTINCT store_name) 3 11. Group By Wir kehren nun zu den Aggregatfunktionen zurück. Erinnern Sie sich an die Berechnung des Gesamtumsatzes für alle Warenhäuser mit Hilfe des Schlüsselworts SUM? Wie kann nun der Gesamtumsatz für jedes einzelne Warenhaus berechnet werden? Dazu sind zwei Dinge erforderlich: Erstens müssen wir sowohl den Warenhausnamen als auch den Gesamtumsatz auswählen. Zweitens müssen wir sicherstellen, dass alle Absatzzahlen nach Warenhäusern gruppiert sind. Die entsprechende SQL-Syntax lautet: SELECT "Spalten_Name1", SUM("Spalten_Name2") FROM "Tabellen_Name" GROUP BY "Spalten_Name1" Nehmen wir zur Verdeutlichung folgende Tabelle: Tabelle Store_Information store_name Sales Los Angeles 1500€ San Diego 250€ Los Angeles 300€ Boston 700€ Date 05.Jan.1999 07.Jan.1999 08.Jan.1999 08.Jan.1999 Wir möchten nun den Gesamtumsatz für jedes Warenhaus ermitteln. Wir geben ein: SELECT store_name, SUM(Sales) FROM Store_Information GROUP BY store_name Ausgabe: store_name Los Angeles San Diego Boston SUM(Sales) 1800€ 250€ 700€ Das Schlüsselwort GROUP BY wird verwendet, wenn mehrere Spalten aus einer Tabelle (oder mehreren Tabellen) ausgewählt werden und mindestens ein arithmetischer Operator in der SELECTAnweisung enthalten ist. In diesem Fall müssen wir nach allen anderen ausgewählten Spalten GRUPPIEREN, d.h. nach allen Spalten außer denjenigen, auf die sich der arithmetische Operator bezieht. 12. Having Eine weitere Möglichkeit besteht darin, die Ausgabe auf Basis der entsprechenden Summe (oder anderer Aggregatfunktionen) zu begrenzen. So könnten wir zum Beispiel nur diejenigen Warenhäuser anzeigen lassen, die einen Umsatz von mehr als 1.500 € haben. Statt der WHEREKlausel in der SQL-Anweisung müssen wir in diesem Fall jedoch die für Aggregatfunktionen vorgesehene HAVING-Klausel verwenden. Die HAVING-Klausel wird üblicherweise am Ende der SQLAnweisung platziert, wobei eine solche Anweisung mit HAVING-Klausel die GROUP BY-Klausel enthalten kann oder auch nicht. Die Syntax für HAVING lautet: SELECT "Spalten_Name1", SUM("Spalten_Name2") FROM "Tabellen_Name" GROUP BY "Spalten_Name1" HAVING (arithmetische Funktionsbedingung) Hinweis: Die GROUP BY-Klausel ist optional. In unserem Beispiel, Tabelle Store_Information, Tabelle Store_Information store_name Sales Los Angeles 1500€ San Diego 250€ Los Angeles 300€ Boston 700€ Date 05.Jan.1999 07.Jan.1999 08.Jan.1999 08.Jan.1999 Wir geben ein: SELECT store_name, SUM(sales) FROM Store_Information GROUP BY store_name HAVING SUM(sales) > 1500 Ausgabe: store_name Los Angeles 13. SUM(Sales) 1800€ Alias Im Folgenden beschäftigen wir uns mit Aliases (= Zweitname). Die zwei am häufigsten verwendeten Aliastypen sind Spaltenalias und Tabellenalias. Spaltenaliases helfen kurz gesagt bei der Organisation der ausgegebenen Daten. Im vorhergehenden Beispiel wurde der Gesamtumsatz immer als SUM(sales) ausgewiesen. Dieser Begriff ist zwar verständlich, aber es lassen sich Situationen vorstellen, in denen die Spaltenkopfzeile kompliziert sein kann (insbesondere bei mehreren arithmetischen Operationen). Die Verwendung eines Spaltenalias würde dann für eine bessere Lesbarkeit sorgen. Die zweite Aliastyp ist der Tabellenalias. Dazu wird ein Alias direkt nach dem Tabellennamen in der FROM-Klausel angegeben. Dies ist nützlich, wenn Daten aus zwei getrennten Tabellen abgerufen werden sollen (also ein Verbund, ein Join, gebildet wird). Der Vorteil der Verwendung eines Tabellenalias im Zusammenhang mit Joins ist offensichtlich. Bevor wir uns jedoch näher mit Join-Verknüpfungen beschäftigen, sehen wir uns die Syntax für Spalten- und Tabellenaliasse an: SELECT "Tabellen_Alias"."Spalten_Name1" "Spalten_Alias" FROM "Tabellen_Name" "Tabellen_Alias" Beide Aliastypen werden direkt nach dem Element platziert, auf das sie sich beziehen, getrennt durch ein Leerzeichen. Wir verwenden wieder die Tabelle Store_Information, Tabelle Store_Information store_name Sales Los Angeles 1500€ San Diego 250€ Los Angeles 300€ Boston 700€ Date 05.Jan.1999 07.Jan.1999 08.Jan.1999 08.Jan.1999 Das Beispiel ist das gleiche wie im Abschnitt GROUP BY, außer dass sowohl der Spaltenalias als auch der Tabellenalias eingegeben wurde: SELECT A1.store_name Store, SUM(A1.Sales) "Total Sales" FROM Store_Information A1 GROUP BY A1.store_name Ausgabe: Store Los Angeles San Diego Boston Total Sales 1800€ 250€ 700€ Beachten Sie den Unterschied im Ergebnis: die Spaltentitel sind anders. Dies ist auf die Verwendung des Spaltenalias zurückzuführen. Statt des etwas kryptischen Begriffs "Sum(Umsatz)", hat die Spalte nun die viel verständlichere Kopfzeile "Total Sales" (Gesamtumsatz). Der Vorteil eines Tabellenalias erschließt sich in diesem Beispiel nicht. Im nächsten Abschnitt zeigt er sich jedoch ganz deutlich. 14. JOIN Sehen wir uns nun den Begriff des Verbunds, des Joins, näher an. Eine korrekte Join-Verknüpfung in SQL setzt viele der bisher vorgestellten Elemente voraus. Nehmen wir an, es liegen die folgenden zwei Tabellen vor, Tabelle Store_Information store_name Los Angeles San Diego Los Angeles Boston Sales 1500€ 250€ 300€ 700€ Tabelle Geography region_name East East West West store_name Boston New York Los Angeles San Diego Date 05.Jan.1999 07.Jan.1999 08.Jan.1999 08.Jan.1999 und wir möchten den Umsatz pro Region ermitteln. Die Tabelle Geography enthält Informationen zu Regionen und Warenhäusern und die Tabelle Store_Information Umsatzdaten für die einzelnen Warenhäuser. Um nun die Umsatzdaten für die jeweiligen Regionen anzeigen zu lassen, müssen wir die Daten der beiden Tabellen kombinieren. Wenn wir uns die beiden Tabellen genauer ansehen, stellen wir fest, dass sie über das gemeinsame Feld "Warenhaus_Name" verknüpft sind. Hier zunächst die SQL-Anweisung, die Verwendung der einzelnen Segmente wird dann anschließend erläutert: SELECT A1.region_name REGION, SUM(A2.Sales) SALES FROM Geography A1, Store_Information A2 WHERE A1.store_name = A2.store_name GROUP BY A1.region_name Ausgabe: REGION East West SALES 700€ 2050€ Die ersten beiden Zeilen weisen SQL an, zwei Felder auszuwählen. Das erste ist das Feld "Region_Name" aus der Tabelle Geography (mit dem Alias REGION) und das zweite die Summe des Felds "Umsatz" aus der Tabelle Store_Information (mit dem Alias UMSATZ). Beachten Sie die Verwendung der Tabellenaliasse: Geography hat den Alias A1 und Store_Information den Alias A2. Ohne die Aliasnamen sähe die erste Zeile wie folgt aus: SELECT Geography.region_name REGION, SUM(Store_Information.Sales) SALES und wäre somit deutlich unübersichtlicher. Im Wesentlichen machen Tabellenaliases die gesamte SQL-Anweisung verständlicher, insbesondere wenn mehrere Tabellen mit einbezogen sind. Sehen wir uns nun die dritte Zeile mit der WHERE-Anweisung genauer an. Hier wird die Verbundbedingung festgelegt. Im vorliegenden Fall möchten wir sicherstellen, dass der Inhalt im Feld "Warenhaus_Name" in der Tabelle demjenigen in der Tabelle Store_Information entspricht. Dies erreichen wir, indem wir die Inhalte gleichsetzen. Diese WHERE-Anweisung ist entscheidend für die richtige Ausgabe. Ohne korrekte WHERE-Anweisung ergibt sich ein kartesischer Verbund. Damit würde die Abfrage alle möglichen Kombinationen der zwei Tabellen (oder wie groß auch immer die Anzahl der Tabellen in der FROM-Anweisung ist) ausgeben. Im vorliegenden Fall wäre das Ergebnis eines kartesischen Verbunds eine Gesamtzahl von 4 x 4 = 16 Zeilen. 15. OUTER JOIN Im vorhergehenden Abschnitt haben wir uns mit dem linken oder inneren Verbund beschäftigt, bei dem Zeilen ausgewählt werden, die den verknüpften Tabellen gemeinsam sind. Nun könnten wir aber auch an Elementen in einer Tabelle interessiert sein, die sich nicht unbedingt in der zweiten Tabelle befinden. In diesem Fall müssen wir den Befehl OUTER JOIN verwenden. Die Syntax für die Verknüpfung als äußerer Verbund in SQL ist datenbankabhängig. In Oracle zum Beispiel platzieren wir ein "(+)" in der WHERE-Klausel auf der anderen Seite der Tabelle, für die alle Zeilen mit aufgenommen werden sollen. Nehmen wir an, es liegen die folgenden zwei Tabellen vor, Tabelle Store_Information store_name Sales Los Angeles 1500€ San Diego 250€ Los Angeles 300€ Boston 700€ Tabelle Geography region_name East East West West Date 05.Jan.1999 07.Jan.1999 08.Jan.1999 08.Jan.1999 store_name Boston New York Los Angeles San Diego und wir möchten den Umsatz für alle Warenhäuser ermitteln. Bei einem regulären Verbund wäre dies nicht möglich, denn es würde das Warenhaus "New York" fehlen, das in der Tabelle Store_Information nicht enthalten ist. Wir müssen daher die zwei Tabellen zu einem äußeren Verbund kombinieren. SELECT A1.store_name, SUM(A2.Sales) SALES FROM Geography A1, Store_Information A2 WHERE A1.store_name = A2.store_name (+) GROUP BY A1.store_name Beachten Sie, dass wir im vorliegenden Fall die Oracle-Syntax verwenden. Ausgabe: store_name SALES Boston 700€ New York Los Angeles 1800€ San Diego 250€ Hinweis: NULL wird ausgegeben, wenn es keine Entsprechung in der zweiten Tabelle gibt. Im vorliegenden Fall ist "New York" nicht in der Tabelle Store_Information enthalten, weshalb die entsprechende Spalte "UMSATZ" den Inhalt NULL hat. 16. Unterabfragen in SQL Es besteht die Möglichkeit, eine SQL-Anweisung in eine andere einzubetten. Geschieht dies in WHERE- oder HAVING-Anweisungen, ergibt sich eine Unteranfrage. Die Syntax sieht folgendermaßen aus: SELECT "Spalten_Name1" FROM "Tabellen_Name1" WHERE "Spalten_Name2" [Vergleichsoperator] (SELECT "Spalten_Name3" FROM "Tabellen_Name2" WHERE [Bedingung]) [Vergleichsoperator] kann ein Gleichungszeichen wie =, >, <, >=, <= sein. Auch ein Textoperator wie "LIKE" ist möglich. Wir verwenden das gleiche Beispiel wie für die SQL-Joins, Tabelle Store_Information store_name Los Angeles San Diego Los Angeles Boston Sales 1500€ 250€ 300€ 700€ Date 05.Jan.1999 07.Jan.1999 08.Jan.1999 08.Jan.1999 Tabelle Geography region_name store_name East Boston East New York West Los Angeles West San Diego und möchten nun mit Hilfe einer Unterabfrage die Umsätze aller Warenhäuser in der Region West ermitteln. Dazu verwenden wir folgende SQL-Anweisung: SELECT SUM(Sales) FROM Store_Information WHERE Store_name IN (SELECT store_name FROM Geography WHERE region_name = 'West') Ausgabe: SUM(Sales) 2050 In diesem Beispiel werden die beiden Tabellen nicht direkt verknüpft, um dann nur die Umsätze für die Warenhäuser in der westlichen Region zu addieren, sondern wir ermitteln erst mit der Unterabfrage, welche Warenhäuser zur Region West gehören und addieren anschließend die entsprechenden Umsätze. 17. UNIONS Der SQL-Befehl UNION vereinigt die Ergebnisse zweier Abfragen. Damit ähnelt UNION in gewisser Hinsicht dem Begriff des JOIN, da beide für aufeinander bezogene Daten in unterschiedlichen Tabellen verwendet werden. Bei UNION gilt jedoch die Einschränkung, dass alle entsprechenden Spalten vom gleichen Datentyp sein müssen. Auch werden mit UNION nur unterschiedliche Werte ausgewählt, also mehrfach vorkommende Ergebnistupel entfernt (ähnlich wie bei SELECT DISTINCT). Die Syntax sieht folgendermaßen aus: [SQL-Anweisung 1] UNION [SQL-Anweisung 2] Nehmen wir an, es liegen die folgenden zwei Tabellen vor, Tabelle Store_Information store_name Sales Los Angeles 1500€ San Diego 250€ Los Angeles 300€ Boston 700€ Date 05.Jan.1999 07.Jan.1999 08.Jan.1999 08.Jan.1999 Tabelle Internet_Sales Date Sales 07.Jan.1999 250€ 10.Jan.1999 535€ 11.Jan.1999 320€ 12.Jan.1999 750€ und wir möchten alle Tage herausfinden, an denen ein Verkaufsvorgang stattgefunden hat. Dazu verwenden wir folgende SQL-Anweisung: SELECT Date FROM Store_Information UNION SELECT Date FROM Internet_Sales Ergebnis: Date 05.Jan.1999 07.Jan.1999 08.Jan.1999 10.Jan.1999 11.Jan.1999 12.Jan.1999 Beachten Sie bitte, dass wir mit der Eingabe "SELECT DISTINCT Date" für eine oder beide der SQLAnweisungen den gleichen Ergebnissatz erhalten. 18. UNION ALL Der SQL-Befehl UNION ALL vereinigt ebenfalls die Ergebnismengen zweier Abfragen. Der Unterschied zwischen UNION ALL und UNION besteht darin, dass mit UNION nur unterschiedliche Werte ausgewählt werden, während bei UNION ALL alle Werte, also auch mehrfach vorkommende Ergebnistupel erhalten bleiben. Die Syntax für UNION ALL sieht folgendermaßen aus: [SQL-Anweisung 1] UNION ALL [SQL-Anweisung 2] Wir verwenden das gleiche Beispiel wie im vorherigen Abschnitt, um den Unterschied zu verdeutlichen. Nehmen wir an, es liegen die folgenden zwei Tabellen vor, Tabelle Store_Information store_name Sales Date Los Angeles San Diego Los Angeles Boston 1500€ 250€ 300€ 700€ 05.Jan.1999 07.Jan.1999 08.Jan.1999 08.Jan.1999 Tabelle Internet_Sales Date Sales 07.Jan.1999 250€ 10.Jan.1999 535€ 11.Jan.1999 320€ 12.Jan.1999 750€ und wir möchten alle Tage herausfinden, an denen ein Verkaufsvorgang stattgefunden hat und ebenso alle Tage, an denen etwas über das Internet verkauft wurde. Dazu verwenden wir folgende SQL-Anweisung: SELECT Date FROM Store_Information UNION ALL SELECT Date FROM Internet_Sales Ergebnis: Date 05.Jan.1999 07.Jan.1999 08.Jan.1999 08.Jan.1999 07.Jan.1999 10.Jan.1999 11.Jan.1999 12.Jan.1999 19. SQL INTERSECT Ähnlich wie der Befehl UNION bezieht sich auch INTERSECT auf zwei SQL-Anweisungen. Der Unterschied besteht darin, dass UNION im Wesentlichen als ODER-Operator wirkt (Auswahl von Werten, die entweder in der ersten oder in der zweiten Anweisung vorkommen), der Befehl INTERSECT hingegen als UND-Operator (nur Auswahl von Werten, die in beiden Anweisungen vorkommen). Die Syntax sieht folgendermaßen aus: [SQL-Anweisung 1] INTERSECT [SQL-Anweisung 2] Nehmen wir an, es liegen die folgenden zwei Tabellen vor, Tabelle Store_Information store_name Sales Los Angeles 1500€ San Diego 250€ Los Angeles 300€ Boston 700€ Date 05.Jan.1999 07.Jan.1999 08.Jan.1999 08.Jan.1999 Tabelle Internet_Sales Date Sales 07.Jan.1999 250€ 10.Jan.1999 535€ 11.Jan.1999 320€ 12.Jan.1999 750€ und wir möchten alle Tage herausfinden, an denen sowohl Verkäufe im Warenhaus als auch über Internet stattgefunden haben. Dazu verwenden wir folgende SQL-Anweisung: SELECT Date FROM Store_Information INTERSECT SELECT Date FROM Internet_Sales Ergebnis: Date 07.Jan.1999 Beachten Sie bitte, dass der Befehl INTERSECT keine Mehrfachergebnisse ausgibt. 20. SQL MINUS Der Befehl MINUS wirkt auf zwei SQL-Anweisungen. Er zieht für die endgültige Antwort von allen Ergebnissen der ersten SQL-Anweisung diejenigen ab, die auch in der zweiten SQL-Anweisung enthalten sind. Enthält die zweite SQL-Anweisung Ergebnisse, die in der ersten nicht vorhanden sind, so werden diese ignoriert. Die Syntax sieht folgendermaßen aus: [SQL-Anweisung 1] MINUS [SQL-Anweisung 2] Wir verwenden wieder das gleiche Beispiel, Tabelle Store_Information store_name Los Angeles San Diego Los Angeles Boston Sales 1500€ 250€ 300€ 700€ Tabelle Internet_Sales Date Sales 07.Jan.1999 250€ 10.Jan.1999 535€ 11.Jan.1999 320€ 12.Jan.1999 750€ Date 05.Jan.1999 07.Jan.1999 08.Jan.1999 08.Jan.1999 und möchten diesmal alle Tage ermitteln, an denen Verkäufe im Warenhaus, jedoch keine Internet-Verkäufe stattgefunden haben. Dazu verwenden wir folgende SQL-Anweisung: SELECT Date FROM Store_Information MINUS SELECT Date FROM Internet_Sales Ergebnis: Date 05.Jan.1999 08.Jan.1999 "05.Jan.1999", "07.Jan.1999", und "08.Jan.1999" sind die unterschiedlichen Werte, die der Befehl "SELECT Date FROM Store_Information" ausgibt. "07.Jan.1999" wird auch von der zweiten SQLAnweisung "SELECT Date FROM Internet_Sales," ausgegeben und somit aus dem endgültigen Ergebnissatz ausgeschlossen. Beachten Sie bitte, dass der Befehl MINUS keine Mehrfachergebnisse ausgibt. 21. SQL Kaskadieren Manchmal ist es erforderlich, die Ergebnisse mehrerer verschiedener Felder zu kombinieren (kaskadieren). In jeder Datenbank gibt es dazu eine Methode: MySQL: CONCAT() Oracle: CONCAT(), || SQL Server: + Die Syntax für CONCAT() sieht folgendermaßen aus: CONCAT(str1, str2, str3, ...): Die Zeichenketten str1, str2, str3 und alle weiteren Zeichenketten werden zusammengefasst. Beachten Sie bitte, dass die Funktion CONCAT() in Oracle nur zwei Argumente erlaubt, es lassen sich damit nur jeweils zwei Zeichenketten gleichzeitig zusammenfügen. Zur Kaskadierung von mehr als zwei Zeichenketten gibt es jedoch in Oracle die Funktion '||'. Sehen wir uns einige Beispiele an. Dabei gehen wir von folgender Tabelle aus: Tabelle Geography region_name East East West West store_name Boston New York Los Angeles San Diego Beispiel 1 - MySQL/Oracle: SELECT CONCAT(region_name,store_name) FROM Geography WHERE store_name = 'Boston'; Ergebnis: 'EastBoston' Beispiel 2 - Oracle: SELECT region_name || ' ' || store_name FROM Geography WHERE store_name = 'Boston'; Ergebnis: 'East Boston' Beispiel 3 - SQL Server: SELECT region_name + ' ' + store_name FROM Geography WHERE store_name = 'Boston'; Ergebnis: 'East Boston' 22. SQL SUBSTRING Die Teilstring-Funktion in SQL dient dazu, nur einen Teil der gespeicherten Daten zu erfassen. Diese Funktion wird in den verschiedenen Datenbänken unterschiedlich aufgerufen: MySQL: SUBSTR(), SUBSTRING() Oracle: SUBSTR() SQL Server: SUBSTRING() Die häufigsten Anwendungsarten sind folgende (wir verwenden im vorliegenden Fall SUBSTR()): SUBSTR(str, pos): Es werden alle Zeichen aus <str> ab der Position <pos> ausgewählt. Beachten Sie, dass diese Option in SQL Server nicht unterstützt wird. SUBSTR(str, pos, len): Beginnend mit dem Zeichen an Position <pos> in der Zeichenkette <str> werden die folgenden Zeichen über die Länge <len> ausgewählt. Dabei gehen wir von folgender Tabelle aus: Tabelle Geography region_name East East West West store_name Boston New York Los Angeles San Diego Beispiel 1: SELECT SUBSTR(store_name, 3) 23. SQL TRIM Die TRIM-Funktion in SQL dient dazu, ein definiertes Präfix oder Suffix von einer Zeichenkette abzuschneiden. Am häufigsten werden Leerzeichen entfernt. Diese Funktion hat in den verschiedenen Datenbänken unterschiedliche Bezeichnungen: MySQL: TRIM(), RTRIM(), LTRIM() Oracle: RTRIM(), LTRIM() SQL Server: RTRIM(), LTRIM() Die Syntax für diese TRIM-Funktionen sieht folgendermaßen aus: TRIM([[Lage] [remstr] FROM ] str): [Lage] kann entweder LEADING, TRAILING oder BOTH sein. Diese Funktion entfernt das Muster [remstr] entweder am Beginn oder am Ende der Zeichenkette oder beides. Ist kein [remstr] angegeben, werden die Leerzeichen entfernt. LTRIM(str): Entfernt alle Leerzeichen am Beginn der Zeichenkette. RTRIM(str): Entfernt alle Leerzeichen am Ende der Zeichenkette Beispiel 1: SELECT TRIM(' Sample '); Ergebnis: 'Sample' Beispiel 2: SELECT LTRIM(' Sample '); Ergebnis: 'Sample ' Beispiel 3: SELECT RTRIM(' Sample '); Ergebnis: ' Sample' Die DDL-Kommandos von SQL 24. CREATE TABLE "Tabellen_Name" Create Table ( "Spalte1" "Datentyp_für_Spalte1", "Spalte2" "Datentyp_für_Spalte2", ); Beispiel: CREATE TABLE abteilung ( abteilungsnr INTEGER NOT NULL, bezeichnung VARCHAR(50), plz CHAR(14), INDEX indexname (name), CONSTRAINT primaerschlüssel PRIMARY KEY (abteilungsnr) ); 25. Create Index CREATE INDEX indexname ON tabellenname (spaltenname); 26. Drop Index DROP INDEX idx_name; 27. Drop Table DROP TABLE "Tabellen_Name"; 28. Drop Domain DROP DOMAIN domain_name; 29. Truncate Table TRUNCATE TABLE "Tabellen_Name" 30. INSERT INTO "Tabellen_Name" Insert Into ("Spalte1", "Spalte2", ... ) VALUES ("Wert1", "Wert2", ...); 31. Alter Table ALTER TABLE mein_kunde ADD plz CHAR(5), DROP spaltenname, CHECK (zahlungsart IN ('R', 'E', 'K')); 32. Update UPDATE "Tabellen_Name" SET "Spalte1" = [Wert] WHERE {Bedingung} 33. DELETE FROM "Tabellen_Name" WHERE {Bedingung} Delete From