SQL Abfragesprache Datenmanipulation - DML
SQL DML-Operationen DML = Data Manipulation Language Sprache zur Veränderung der Daten Operationen Daten selektieren Daten einfügen Daten ändern Daten löschen SQL DML 1-2
SQL Datenselektion Zum lesenden Zugriff auf Daten und Katalogtabellen Grundform: Der SFW Block <select_exp> := SELECT [ ALL DISTINCT ] { <select_item> //, }+ FROM { <table_ref> //, }+ [ WHERE <cond_exp> ] [ GROUP BY { <column_name> //, }+ ] [ HAVING <cond_exp> ] [ ORDER BY { <order_item>//, }+ ] SQL DML 1-6
SFW-Block Bedeutung SELECT-Klausel Projektionsliste mit Umbenennungen arithmetische Operationen und Aggregatfunktionen FROM-Klausel beschreibt die verwendete Relationen Umbenennungen von Relationen Formulierung von Joins WHERE-Klausel Selektions- und Join-Bedingungen SQL DML 1-7
SFW: Einfaches Beispiel Finde die Namen und Telefonnummern aller Angestellten aus dem Projekt Nummer 23: SELECT VName, TelNr FROM Personal WHERE ProjNr = 23 PersNr VName TelNr ProjNr 001 Tick 145 21 002 Trick 187 22 003 Gustav 342 23 004 Donald 376 22 005 Daisy 343 24 006 Gundula 984 23 VName TelNr Gustav 342 Gundula 984 SQL DML 1-8
SFW mit Sortierung Um ausgewählte Daten sortiert zurückzugeben gibt es den Zusatz: ORDER BY { <order_item>//, }+ <order_item> := <column_name> [ ASC DESC ] Beispiel: SELECT VName, TelNr FROM Personal WHERE ProjNr = 23 ORDER BY VName ASC Anmerkung: Bei SQL89 auch Bezug auf Spalte durch Angabe der Position in der SELECT-Liste möglich. SQL DML 1-9
SQL zur Veränderung der Daten Einfügen von Sätzen: INSERT Modifikation bestehender Sätze: UPDATE Löschen von Sätzen: DELETE SQL DML 1-10
INSERT: Einfügen von Sätzen Eingefügt werden können: Explizit angegebene Daten. Daten, die aus der DB berechnet wurden. Syntax (vereinfacht): INSERT INTO <table_name> [ ( {<column_name> //, }+ ) ] { DEFAULT VALUES VALUES ( {<insert_atom> //, }+ ) <select_exp> } SQL DML 1-11
INSERT: Beispiele Explizite Werte: INSERT INTO Projekt VALUES ( 25, 5000, 'Abt34' ) INSERT INTO Projekt (projnr, abtnr) VALUES ( 25, 'Abt34' ) Anmerkung: Ohne Feldangabe nie in Programmen verwenden! Berechnete Werte: INSERT INTO GrossesProjekt SELECT * FROM Projekt WHERE budget > 10000 SQL DML 1-12
UPDATE: Ändern von Sätzen Syntax: UPDATE <table_name> SET {<assignment>//,}+ [ WHERE <cond_exp> ] <assignment> := <column_name> = { <scalar_exp> DEFAULT NULL } Beispiel: UPDATE Projekt SET AbtNr = NULL SQL DML 1-13
UPDATE: Beispiele Erhöhung des Budgets für Projekt Nr. 47: UPDATE Projekt SET budget = budget + 100 WHERE ProjNr = 47 Initialisierung für Projekt 48 durchführen: UPDATE Projekt SET budget = DEFAULT, AbtNr = DEFAULT WHERE ProjNr = 48 SQL DML 1-14
DELETE: Löschen von Sätzen Syntax: DELETE FROM <table_name> [ WHERE <cond_exp> ] Bedeutung: Die ausgewählten Sätze werden gelöscht. Beispiel: DELETE FROM Projekt WHERE ProjNr = 47 OR ProjNr = 48 SQL DML 1-15
SELECT-Klausel Syntax: SELECT [ ALL DISTINCT ] { <select_item> //, }+ <select_item> := { [<range_variable>.] <scalar_exp> [ [ AS ] <column_name> ] } Bedeutung: Auswahl aller Spalten: SELECT * Elimination von Duplikaten: SELECT DISTINCT Der Default ist SELECT ALL SQL DML 1-16
SELECT Klausel - Bedeutung Der skalare Audruck ist in der Regel: Spaltenname ( durch Funktionen ) berechneter Wert Aggregatfunktion Beispiele: SELECT NName, VName, Gehalt SELECT ( gehalt * 1.32 ) AS usd_gehalt SELECT ( NName ', ' VName ) AS Name SQL DML 1-17
Skalare Funktionen Ausschnitt aus den möglichen Funktionen: + - * / - übliche Arithmetik CHAR_LENGTH - Länge einer Zeichenkette - Konkatenation LOWER, UPPER - Umwandlung in Groß-/Kleinbuchstaben COALESCE - Ersetzen von NULL-Werten POSITION (string1 IN string2) - Positionsbestimmung SUBSTRING (string FROM anfang FOR length) - Teil einer Zeichenkette TRIM ({LEADING TRAILING BOTH} pad FROM string) - Entfernen führender oder abschl. Zeichen CAST - Typkonvertierung CASE - Umsetzen von Werten SQL DML 1-18
Aggregatfunktionen Syntax: <aggregate_function> := { COUNT ( ) { AVG MAX MIN SUM COUNT } ( [ ALL DISTINCT ] <scalar_exp> ) } Bedeutung: COUNT( ) liefert die Anzahl der Ergebniszeilen zurück. MIN(MAX) liefert den kleinsten(größten) Wert SUM liefert die Summe AVG liefert den Mittelwert SQL DML 1-20
Aggregatfunktionen - Beispiele MIN, MAX SUM AVG SELECT MIN( NName ), MAX( NName ) FROM Personal SELECT SUM( Gehalt ) FROM Personal WHERE ProjNr = 48 SELECT AVG( Gehalt ) FROM Akte WHERE Position = 'Abteilungsleiter' SQL DML 1-21
Aggregatfunktionen - Beispiele (2) COUNT SELECT COUNT( ) FROM Personal WHERE ProjNr = 47 SELECT FROM COUNT (DISTINCT Position) Akte SQL DML 1-22
FROM-Klausel Angabe der relevanten Tabellen und Verknüpfung von diesen. Syntax: FROM { <table_ref> //, }+ <table_ref> := { <table_name> [ [AS] <range_var> [ ( {<column_name>//,} ) ] ] ( <table_exp> ) [ [AS] <range_var> [ ( {<column_name>//,} ) ] ] <join-table-exp> } SQL DML 1-23
FROM-Klausel - Kreuzprodukt Einfaches Kreuzprodukt (Cross Join): SELECT FROM Projekt, Abteilung Ab SQL92: SELECT FROM Projekt CROSS JOIN Abteilung Einfache Verknüpfung (Nachbildung Join) SELECT projnr, a.abtname FROM Projekt p, Abteilung a WHERE a.projnr = p. projnr SQL DML 1-24
(Inner) Join In der ersten Version des Standards (SQL89): Liste von Tabellen in FROM-Klausel Join-Bedingung irgendwo in WHERE-Bedingung Semantik: In FROM wird Kreuzprodukt aller beteiligter Tabellen gebildet Join-Bedingung als normales Selektionskriterium Schlecht wartbar, fehleranfällig! Ab SQL92: vollständige Angabe der Join-Bedingung in FROM SQL DML 1-25
SQL92: Join - Syntax Join Syntax: <join_table_expr> := { <table_ref> [NATURAL] [<join_type>] JOIN <table_ref> [ ON <cond_exp> USING ( {<column>//,}+ ) ] <table_ref> CROSS JOIN <table_ref> ( <join_table_expr> ) } < join_type> := { INNER LEFT [OUTER] RIGHT [OUTER] FULL [OUTER] UNION } SQL DML 1-26
Natural Join Das Pendant zur JOIN-Operation der relationalen Algebra Beispiel: SELECT projnr, abtnr, abtname FROM Projekt NATURAL JOIN Abteilung Achtung: Nur für Abfragen auf der Konsole nutzen Nie in Programmen verwenden! Immer bedenken, dass Tabellen sich ändern und neue Spalten jederzeit hinzugefügt werden können SQL DML 1-27
Inner Join - Beispiel Auswahl aller Angestellten mit den zugehörigen Abteilungen: SELECT Name, AbtName FROM Personal JOIN Projekt ON Personal.ProjNr = Projekt.ProjNr JOIN Abteilung ON Projekt.AbtNr = Abteilung.AbtNr Bei gleichen Attributnamen ist auch die Kurzform möglich: SELECT Name, AbtName FROM Personal JOIN Projekt USING (ProjNr) JOIN Abteilung USING (AbtNr) SELECT Name, AbtName FROM Personal NATURAL JOIN Projekt JOIN Abteilung USING (AbtNr) SQL DML 1-28
Syntax: Die WHERE-Bedingung WHERE <cond_exp> <cond_exp> := { <cond_term> <cond_exp> OR <cond_term> } <cond_term> := { <cond_factor> <cond_ term > AND <cond_ factor > } <cond_factor> := [ NOT ] { <simple_cond> (<cond_exp>) } [ IS [ NOT ] { TRUE FALSE UNKNOWN } ] <simple_cond> := { <comp_cond> <between_cond> <like_cond> <in_cond> <match_cond> <all_or_any_cond> <exists_cond> <unique_cond> <overlaps_cond> <test_for_null> } SQL DML 1-29
Vergleiche Syntax: <comp_cond> := <row_constr> <comp_operator> <row_constr> <comp_operator> := { = < <= > >= <> } <row_constr> := { <scalar_exp> ( {<scalar_exp>//,}+ ) ( <table_exp> ) } Beispiele: gehalt >= 25 ( name, gehalt ) = ( 'Meier', 37 ) Anmerkungen: SQL89: <row_constr> := <scalar_exp>!! <table_exp> darf nur 1 Zeile liefern! SQL DML 1-30
BETWEEN-Bedingung Syntax: <between_cond> := <row_constr> [ NOT ] BETWEEN <row_constr> AND <row_constr> Beispiel: gehalt BETWEEN 25 AND 35 Anmerkungen: "y BETWEEN x AND z" ist vollkommen äquivalent zu "x <= y AND y <= z" Vorsicht bei Annahmen über die Codierung! Folgendes funktioniert zwar bei ASCII, aber nicht bei EBCDIC- Codierung: val BETWEEN 'A' AND 'z' SQL DML 1-31
LIKE-Bedingung Syntax: <like_cond> := <char_string_exp> [ NOT ] LIKE <pattern> [ ESCAPE <escape> ] Beispiele: name LIKE 'Schmi%' name LIKE 'Schmi ' name LIKE '%ä%' name LIKE '\_%' ESCAPE '\' Bedeutung: 2 Jokerzeichen: '%' - steht für beliebig viele Zeichen '_' - steht für genau 1 Zeichen SQL DML 1-32
Übung: SQL DML Tabellen: Personal ( PersNr, NName, Vname, ProjNr, Gehalt ) Akte ( PersNr, Datum, Position, Gehalt ) Projekt ( ProjNr, Budget, AbtNr ) Abteilung ( AbtNr, AbtName, Budget, ChefNr ) Aufgaben: Welche Projekte verfügen über ein höheres Budget als ganze Abteilungen? Ermitteln Sie die Gehaltsentwicklung des Angestellten Dagobert". Ermitteln Sie das Budget aller Projekte der Abteilung "Marketing". SQL DML 1-33
Gruppierung Berechnung von Aggregaten für einzelne Gruppen. Erinnerung: Der SFW Block <select_exp> := SELECT [ ALL DISTINCT ] { <select_item> //, }+ FROM { <table_ref> //, }+ [ WHERE <cond_exp> ] [ GROUP BY { <column_name> //, }+ ] [ HAVING <cond_exp> ] SQL DML 1-34
Gruppierung: Beispiele Beispiel: Berechnung der Summe der Budgets der Projekte aller Abteilungen: SELECT AbtNr, SUM( Budget ) FROM Projekt GROUP BY AbtNr Beispiel: Anzahl der Mitarbeiter jeder Abteilung: SELECT AbtNr, COUNT( ) FROM Projekt JOIN Personal USING (ProjNr) GROUP BY AbtNr SQL DML 1-35
HAVING-Klausel Zum Ausschluss ganzer Gruppen aus dem Ergebnis. Kann sich nicht auf Spalten beziehen, die nicht aggregiert sind. Im Ggs. zu WHERE können Aggregationsfunktionen direkt verwendet werden. Beispiel: Es sollen nur die Abteilungen ausgegeben werden, deren Summe an Projektbudgets über 5000 liegt: SELECT AbtNr, SUM( Budget ) FROM Projekt GROUP BY AbtNr HAVING SUM( Budget ) > 5000 SQL DML 1-36
Weitere Beispiele Finde alle Abteilungen mit 3 oder mehr Projekten. Gib die Abteilung sowie die Summe der Projektbudgets aus, sortiert nach dem Budget: SELECT AbtNr, SUM( Budget ) AS AbtBudget FROM Projekt GROUP BY AbtNr HAVING COUNT( ) >= 3 ORDER BY AbtBudget DESC, AbtNr ASC SQL DML 1-37
SQL Übung Gruppierung Erstellen Sie eine Liste der Projekte (projnr, budget, dgehalt) mit dem jeweiligen Durchschnittsgehalt in diesem Projekt. Die Projekte sind nach dem Durchschnittsgehalt absteigend zu sortieren. Finden Sie alle Abteilungen, für die weniger als 5 Mitarbeiter arbeiten. SQL DML 1-38
Schachtelung von Anfragen Subqueries Anfragen können beliebig ineinander geschachtelt werden: <in_cond> := <row_constr> [ NOT ] IN ( <table_exp> ) <match_cond> := <row_constr> MATCH [ UNIQUE ] ( <table_exp> ) <all_or_any_cond> := <row_constr> <comp_operator> { ALL ANY SOME } ( <table_exp> ) <exists_cond> := EXISTS ( <table_exp> ) <unique_cond> := UNIQUE ( <table_exp> ) SQL DML 1-39
Beispiel: IN-Bedingung Finde alle Angestellten, die Müller, Meier oder Meyer heißen: SELECT FROM WHERE PersNr, NName Personal NName IN ('Müller', 'Meier', 'Meyer') Finde alle Angestellten, die in einem Projekt mit Budget < 25000 arbeiten: SELECT NName FROM Personal WHERE ProjNr IN ( SELECT ProjNr FROM Projekt WHERE Budget < 25000 ) SQL DML 1-40
JOIN IN Gleichwertig (da ProjNr Primary Key): SELECT NName FROM Personal WHERE ProjNr IN ( SELECT ProjNr FROM Projekt WHERE Budget < 25000 ) SELECT NName FROM Personal JOIN Projekt USING (ProjNr) WHERE Budget < 25000 SQL DML 1-41
Beispiel: ANY, ALL, SOME Finde die Spitzenverdiener unter den Angestellten: SELECT NName FROM Personal WHERE Gehalt >= ALL ( SELECT Gehalt FROM Personal ) Finde diejenigen, die mit dem Gehalt nicht am oberen Ende liegen: SELECT NName FROM Personal WHERE Gehalt < ANY ( SELECT Gehalt FROM Personal ) SQL DML 1-42
Beispiel: EXISTS Finde alle Projekte, an denen niemand arbeitet: SELECT ProjNr FROM Projekt WHERE NOT EXISTS ( SELECT * FROM Personal WHERE ProjNr = Projekt.ProjNr ) Anmerkung: Referenzen auf die äußere Tabelle erfordern Aliasnamen, wenn die gleiche Tabelle auf mehreren Ebenen verwendet wird. SQL DML 1-43
Mengenoperationen Vereinigung UNION [ALL] Schnittmenge INTERSECT [ALL] Minus-Operation EXCEPT [ALL] A A A B B B Die Operationen können nur auf Relationen mit "kompatiblen" Attributen ausgeführt werden. SQL DML 1-45
Beispiel: Vereinigung Finde alle Projekte, an denen ein "Meier" teilnimmt, oder die zur Abteilung "Buchhaltung" gehören: SELECT FROM WHERE UNION ProjNr Personal NName = 'Meier' SELECT FROM WHERE ProjNr Projekt JOIN Abteilung USING (AbtNr) AbtName = 'Buchhaltung' SQL DML 1-46
Beispiel: Schnittmenge Alle Projekte, in denen ein "Meier" arbeitet und die zur Abteilung "Buchhaltung" gehören: SELECT FROM WHERE INTERSECT ProjNr Personal NName = 'Meier' SELECT FROM WHERE ProjNr Projekt JOIN Abteilung USING (AbtNr) AbtName = 'Buchhaltung' SQL DML 1-47
Beispiel: Differenz Beispiel: Finde alle Projekte, an denen ein "Meier" teilnimmt, und die nicht zur Abteilung "Buchhaltung" gehören: SELECT FROM WHERE EXCEPT ProjNr Personal NName = 'Meier' SELECT FROM WHERE ProjNr Projekt JOIN Abteilung USING (AbtNr) AbtName = 'Buchhaltung' SQL DML 1-48