1 Structured Query Language - SQL



Ähnliche Dokumente
SQL für Trolle. mag.e. Dienstag, Qt-Seminar

Mengenvergleiche: Alle Konten außer das, mit dem größten Saldo.

SQL SQL. SQL = Structured Query Language (SEQUEL) IBM San Jose Research Laboratory SYSTEM R. Grundlagen der Datenbanksysteme I

Informatik 12 Datenbanken SQL-Einführung

7. Übung - Datenbanken

Nachtrag: Farben. Farbblindheit. (Light und Bartlein 2004)

DATENBANKEN SQL UND SQLITE VON MELANIE SCHLIEBENER

Details zu den Ausdrücken nach FROM, WHERE, GROUP BY und HAVING finden Sie in den Abschnitten über JOIN, WHERE und GROUP BY.

Ein Ausflug zu ACCESS

SQL (Structured Query Language) Schemata Datentypen

Einführung in SQL. Sprachumfang: Indizes. Datensätzen. Zugriffsrechten

SQL. strukturierte Datenbankabfragesprache eine Datenbanksprache zur. Structured Query Language:

Eine völlig andere Form Abfragen zu erstellen ist, sie mit Hilfe der Datenbankabfragesprache SQL zu gestalten.

Labor 3 - Datenbank mit MySQL

Binäre Bäume. 1. Allgemeines. 2. Funktionsweise. 2.1 Eintragen

Aufbau des SELECT-Befehls. Im Folgenden werden zunächst Abfragen aus einer Tabelle vorgenommen.

Berechnungen in Access Teil I

3. Das Relationale Datenmodell

SQL structured query language

Vorlesung Dokumentation und Datenbanken Klausur

Carl-Engler-Schule Karlsruhe Datenbank 1 (5)

IV. Datenbankmanagement

Die bisher bereits bekannten Aggregatsfunktionen MIN, MAX, SUM, AVG, COUNT, VARIANCE und STDDEV wurden um FIRST und LAST erweitert.

1 Mathematische Grundlagen

Unterabfragen (Subqueries)

Einführung in SQL. 1. Grundlagen SQL. Structured Query Language. Viele Dialekte. Unterteilung: i. DDL (Data Definition Language)

SQL Teil 2. SELECT Projektion Selektion Vereinigung, Schnitt, Differenz Verbund Komplexer SELECT-Ausdruck

Oracle SQL Tutorium - Wiederholung DB I -

Handbuch ECDL 2003 Basic Modul 5: Datenbank Grundlagen von relationalen Datenbanken

Funktionsbeschreibung. Lieferantenbewertung. von IT Consulting Kauka GmbH

Dynamisches SQL. Folien zum Datenbankpraktikum Wintersemester 2009/10 LMU München

SQL Tutorial. SQL - Tutorial SS 06. Hubert Baumgartner. INSO - Industrial Software

5.3 Datenänderung/-zugriff mit SQL (DML)

Sructred Query Language

Inhalt. 1 Einleitung AUTOMATISCHE DATENSICHERUNG AUF EINEN CLOUDSPEICHER

Universität Augsburg, Institut für Informatik WS 2006/2007 Dr. W.-T. Balke 27. Nov M. Endres, A. Huhn, T. Preisinger Lösungsblatt 5

Datenbanken Kapitel 2

Grundfunktionen und Bedienung

OP-LOG

Stellen Sie bitte den Cursor in die Spalte B2 und rufen die Funktion Sverweis auf. Es öffnet sich folgendes Dialogfenster

Professionelle Seminare im Bereich MS-Office

Fachbericht zum Thema: Anforderungen an ein Datenbanksystem

Oracle: Abstrakte Datentypen:

Suche schlecht beschriftete Bilder mit Eigenen Abfragen

Diese Ansicht erhalten Sie nach der erfolgreichen Anmeldung bei Wordpress.

DBS ::: SERIE 5. Join Right Semi- Join Left Semi-Join Projektion Selektion Fremdschlüssel. Kreuzprodukt

4. AUSSAGENLOGIK: SYNTAX. Der Unterschied zwischen Objektsprache und Metasprache lässt sich folgendermaßen charakterisieren:

Kalkülteil. Structured Query Language, SQL. 1. Semantik: erzeuge alle Kombinationen von Tupeln

Der Aufruf von DM_in_Euro 1.40 sollte die Ausgabe 1.40 DM = Euro ergeben.

Datenbanken für Online Untersuchungen

Access [basics] Gruppierungen in Abfragen. Beispieldatenbank. Abfragen gruppieren. Artikel pro Kategorie zählen

Abfragen: Grundbausteine

Hilfedatei der Oden$-Börse Stand Juni 2014

4. BEZIEHUNGEN ZWISCHEN TABELLEN

Excel Pivot-Tabellen 2010 effektiv

Michaela Weiss 01. April Lerneinheit 4: Relationale Datenbanken am Beispiel von MySQL

mysql - Clients MySQL - Abfragen eine serverbasierenden Datenbank

Outlook. sysplus.ch outlook - mail-grundlagen Seite 1/8. Mail-Grundlagen. Posteingang

Virtueller Seminarordner Anleitung für die Dozentinnen und Dozenten

Wir basteln einen Jahreskalender mit MS Excel.

Datenbanken SQL Einführung Datenbank in MySQL einrichten mit PhpMyAdmin

Erklärung zum Internet-Bestellschein

Lineargleichungssysteme: Additions-/ Subtraktionsverfahren

SQL: statische Integrität

Im Original veränderbare Word-Dateien

Berechtigungen im Kalender Anleitung für die Rechtevergabe im Outlook Kalender FHNW, Services, ICT

Das große ElterngeldPlus 1x1. Alles über das ElterngeldPlus. Wer kann ElterngeldPlus beantragen? ElterngeldPlus verstehen ein paar einleitende Fakten

Access Grundlagen für Anwender. Susanne Weber. 1. Ausgabe, 1. Aktualisierung, Juni 2013

Anwendungsentwicklung Datenbanken SQL. Stefan Goebel

Auswahlabfragen mit ACCESS

Zeichen bei Zahlen entschlüsseln

Schlüssel bei temporalen Daten im relationalen Modell

Handbuch B4000+ Preset Manager

Primzahlen und RSA-Verschlüsselung

Views in SQL. 2 Anlegen und Verwenden von Views 2

Web-Kürzel. Krishna Tateneni Yves Arrouye Deutsche Übersetzung: Stefan Winter

DB2 Kurzeinführung (Windows)

Datumsangaben, enthält mindestens Jahr, Monat, Tag

HANDBUCH PHOENIX II - DOKUMENTENVERWALTUNG

Arbeiten mit einem lokalen PostgreSQL-Server

1. Man schreibe die folgenden Aussagen jeweils in einen normalen Satz um. Zum Beispiel kann man die Aussage:

Jede Zahl muss dabei einzeln umgerechnet werden. Beginnen wir also ganz am Anfang mit der Zahl,192.

Übung Datenbanken in der Praxis. Datenmodifikation mit SQL

Quick-Guide Web Shop. Kurzanleitung für die Benutzer des Bernd Kraft Webshops

Variablen & erweiterte Aktionen nutzen

Austausch- bzw. Übergangsprozesse und Gleichgewichtsverteilungen

pro4controlling - Whitepaper [DEU] Whitepaper zur CfMD-Lösung pro4controlling Seite 1 von 9

Handbuch zur Anlage von Turnieren auf der NÖEV-Homepage

So importieren Sie einen KPI mithilfe des Assistenten zum Erstellen einer Scorecard

Access [basics] Rechnen in Berichten. Beispieldatenbank. Datensatzweise berechnen. Berechnung im Textfeld. Reporting in Berichten Rechnen in Berichten

Folge 19 - Bäume Binärbäume - Allgemeines. Grundlagen: Ulrich Helmich: Informatik 2 mit BlueJ - Ein Kurs für die Stufe 12

Kommunikations-Management

TU München, Fakultät für Informatik Lehrstuhl III: Datenbanksysteme Prof. Alfons Kemper, Ph.D.

Datenaustausch mit Datenbanken

5 DATEN Variablen. Variablen können beliebige Werte zugewiesen und im Gegensatz zu

In diesem Thema lernen wir die Grundlagen der Datenbanken kennen und werden diese lernen einzusetzen. Access. Die Grundlagen der Datenbanken.

Doku zur Gebäudebrüter Datenbank

Transkript:

1 Structured Query Language - SQL Andreas Schmidt 1.1 Übersicht Ende der 60er Jahre entwickelte E.F. Codd bei IBM das relationale Datenmodell [Cod70]. Es ist streng formal aufgebaut, basierend auf der Relationenalgebra und dem Relationenkalkül. Das Modell besticht sowohl durch seine Einfachheit, als auch durch seine Exaktheit. Codd beschreibt in seinem Modell sowohl die strukturellen Eigenschaften, Integritätsaspekte als auch eine Reihe von Operationen auf den Daten. Ein Großteil der sich heute produktiv im Einsatz befindlichen Datenbanksysteme basieren auf diesem Modell. Bekannte Vertreter sind etwa Oracle, der Microsoft SQL-Server, sowie die Open Source Produkte MySQL und PostgreSQL. SQL stellt die Anfrage und Datendefinitionssprache für relationale Datenbanksysteme dar. SQL ist deskriptiv, d.h. der Anwender formuliert welche Informationen er haben möchte, nicht jedoch, wie er an diese Informationen kommt. SQL ist mengenorientiert. 1.2 Grundlegende Konzepte des Relationenmodells Bevor auf SQL als Anfrage- und Datendefinitionssprache für relationale Datenbanken eingegangen wird, werden im Folgenden einige elementare Kenntnisse des Relationenmodells vermittelt, die für das spätere Verständnis von SQL hilfreich sind. Eine ausführliche und detailierte Einführung in das Modell findet sich in [SKS01]. Die Einführung soll anhand der beiden in Abbildung 1.1 dargestellten Relationen country und city erfolgen. Abb. 1.1: Struktur relationaler Datenbanken

2 1 SQL 1.2.1 Struktur Zentrale Komponente in Codds Modell ist die Relation. Eine Relation besteht aus einer Anzahl von Tupeln, welche die Datensätze repräsentieren. Die Struktur einer Relation (und somit auch der in ihr enthaltenen Tupel) wird durch das Relationenschema vorgegeben. Ein Relationenschema besitzt einen eindeutigen Namen und wird durch eine Menge von Attributen beschrieben, die jeweils einen bestimmten Wertebereich (Domäne) besitzen. Es beschreibt somit eine Struktur, vergleichbar einem Struct in C/C++ oder einem Record in Pascal. Dabei ist aber zu beachten, dass die Werte der Attribute atomar sein müssen, d.h. keine mengenwertigen oder strukturierten Daten repräsentieren dürfen. Die Gesamtheit aller Relationenschemata bildet dann das Datenbankschemata. Anschaulich wird eine Relation als Tabelle dargestellt. Die Attribute des Relationenschemas werden zu den Spaltenbezeichnern, die Zeilen der Tabelle repräsentieren die Tupel und die Werte in den Tabellenfeldern entsprechen denen der Wertebereiche ihrer Attribute. Bei der Abbildung von Relationen auf Tabellen sind jedoch zwei Punkte zu beachten, die aus der Tatsache herrühren, dass es sich bei einer Relation um eine mathematische Menge von Tupeln handelt: 1. In einer Menge gibt es keine Reihenfolge, das heißt die Reihenfolge der Datensätze (Zeilen) in den Tabellen ist willkürlich. 2. Mengen erlauben keine Duplikate, d.h. es darf keine zwei Datensätze in einer Tabelle geben, die identisch sind. 1.2.2 Integrität Das Relationenmodell kennt weiterhin den Begriff des Primärschlüssels. Dabei handelt es sich um ein oder mehrere Attribute eines Relationenschemas, so dass es in dieser Relation keine zwei Tupel geben kann, die für dieses Attribut oder Attributkombination identische Attributwerte besitzen. Mittels des Primärschlüssels ist es somit möglich, einzelne Tupel zu identifizieren. Dieser Sachverhalt wird im Relationenmodell dazu genutzt um Beziehungen zwischen Datensätzen herzustellen. In Abbildung 1.1 sind die Attribute, die den Primärschlüssel bilden unterstrichen. Da es in einer Menge von Datensätzen keine Duplikate gibt ist gewährleistet, dass es für jede Relation einen Primärschlüssel gibt. Spätestens durch die Hinzunahme aller Attribute eines Relationenschemas lässt sich ein Primärschlüssel konstruieren. Aufbauend auf dem Primärschlüssel existiert das Konzept des Fremdschlüssels mit dem sich Beziehungen zwischen Datensätzen modellieren lassen. Ein Fremdschlüssel ist ein Attribut oder eine Attributkombination, die auf den Primärschlüssel einer Relation 1 verweist. Dabei muss gesichert sein, dass der Wert des Fremdschlüssels immer auf ein existierendes Tupel verweist, d.h. dass der Attributwert oder die Attributwertkombination des Fremdschlüssels identisch mit einem existierenden Primärschlüsselwert ist. Dieser Sachverhalt wir als referentiellen Integrität eines Datenbanksystems bezeichnet. In Abbildung 1.1 sind zwei Fremdschlüsselbeziehungen zu sehen. Zum einen besitzt die Relation country einen Fremdschlüssel, bestehend aus den Attributen code, capital 1 dabei kann es sich um eine beliebige andere- oder aber auch um die selbe Relation handeln.

1.3 Organisation der Sprache 3 und province, welcher die Hauptstadt des Landes referenziert. Beispielhaft ist dies am Datensatz der Schweiz dargestellt. Zum zweiten besitzt die Relation city den Fremdschlüssel country, welcher das Land identifiziert in dem sich die Stadt befindet. Dies ist beispielhaft anhand der Städte Frankreichs angedeutet. Weitere mögliche Integritätsbedingungen sind die Einschränkung des Wertebereichs für einzelne Attribute, das Erzwingen von Einträgen für bestimmte Attribute und das Erzwingen der Eindeutigkeit von Attributwerten innerhalb einer Relation. 1.2.3 Operationen Codd formuliert eine Reihe von Operationen auf den Relationen. Im einzelnen handelt es sich dabei um Restriktion, Projektion, Kartesisches Produkt, Join, Vereinigung, Durchschnitt und Differenz. All diese Operationen besitzen eine oder mehrere Relationen als Eingabe und liefern eine Relation als Ausgabe zurück [Dat05]. Dies bedeutet insbesondere, dass die Ausgabe einer Operation, stets wieder als Eingabe einer anderen Operation dienen kann, was die Formulierung geschachtelter relationaler Ausdrücke erlaubt. In Abschnitt 1.6.2 wird die Umsetzung obiger Operationen auf SQL-Statements beschrieben. 1.3 Organisation der Sprache SQL hat inzwischen eine Reihe von Standardisierungsrunden durchlaufen. Das American National Standards Institute (ANSI) setzte 1986 den ersten Standard (SQL1 oder SQL-86). Weitere Standardisierungen fanden 1989 und 1992 (bekannt als SQL2 bzw. SQL-92) statt, sowie zuletzt die als SQL3 (SQL-99) bekannt gewordene Aktualisierung des Standards im Jahr 1999. SQL ist weiterhin auch von der International Standard Organisation (ISO) anerkannt. Im SQL2 Standard werden drei Anweisungsklassen definiert, die auch die Grundlage für die Strukturierung in diesem Kapitel bilden. Datenmanipulationssprache (Data Manipulation Language, DML): Diese Klasse enthält Sprachelemente zur Bearbeitung von Daten. Operationen sind das Einfügen (insert), Löschen (delete), Modifizieren (update) und Abfragen (select) von Daten. Die zur DML gehörenden Operatoren werden zur Laufzeit einer Datenbankanwendung eingesetzt, um auf die Daten in den zuvor mittels der DDL (s.u.) angelegten Tabellen zuzugreifen. Datendefinitionssprache (Data Definition Language, DDL): Die Sprachelemente in dieser Klasse erlauben das Anlegen und Modifizieren der Datenstrukturen. Typische Vertreter sind die Sprachelemente create table, alter table, etc. Die Befehle dieser Klasse werden hauptsächlich zur Entwicklungszeit einer Datenbankanwendung eingesetzt. Sie erlauben die Definition der Datenstrukturen und Tabellen, auf die dann zur Laufzeit mittels den Befehlen der DML lesend und schreibend zugegriffen wird.

4 1 SQL Datensteuerungssprache (Data Control Language, DCL): Die Sprachelemente in dieser Klasse erlauben das Anlegen und Modifizieren von Benutzern und Rollen sowie die Vergabe von Zugriffs- und Systemrechten. Typische Vertreter sind die Befehle create user zum Anlegen von neuen Benutzern sowie grant und revoke mit denen bestimmte Berechtigungen vergeben und wieder entzogen werden können. 1.4 Datentypen In Abschnitt 1.2.1 wurde gesagt, das jede Spalte einer Relation einen bestimmten Wertebereich hat. Diese Wertebereiche werden in SQL durch Datentypen festgelegt. Unabhängig vom konkreten Datenbanksystem 2 lassen sich die Datentypen in folgende Kategorien untergliedern: Zeichenketten: Erlauben das Speichern von beliebigen Kombinationen von Zeichen. Es wird zwischen variabel langen Datentypen (varchar(<size>), CLOB 3 ) und Datentypen mit fester Länge (char(<size>)) unterschieden. Bei Datentypen mit fester Länge wird die Zeichenkette am Ende mit Leerzeichen aufgefüllt, bei Datentypen variabler Länge wird nach dem letzten Zeichen abgeschnitten. Zum Teil kann eine Obergrenze, wie viel Zeichen maximal gespeichert werden dürfen, angegeben werden, teils sind die Grenzen fest vorgegeben. Weiterhin gibt es Varianten obiger Typen die mit verschiedenen nationalen Zeichensätzen umgehen können (z.b. nvarchar<size>). Numerisch: Es können sowohl ganze Zahlen als auch Fließkommazahlen gespeichert werden. Die Typen unterscheiden sich in ihrer Genauigkeit und Stellenzahl. Beim Datentyp float kann bei der Definition beispielsweise die Anzahl der Stellen vor und nach dem Komma mit angegeben werden. Vertreter numerischer Datentypen sind integer, smallint, numeric, float, real und double precision. Zeitlich: Es gibt Datentypen zum Speichern von Datum (Date) und Uhrzeit (Time), mit und ohne Zeitzone. Weiterhin gibt es den Datentyp Interval, der eine Zeitdauer aufnimmt. Binär: Der Datentyp BLOB 4 speichert beliebige binäre Zeichenketten. Die Größe liegt dabei meist im Gigabyte Bereich. Boolean: Datentyp zur Aufnahme der Werte TRUE und FALSE. Bit-String: Datentyp zur Aufnahme binärer Daten, mit fester oder variabler Länge. Es gibt den speziellen Wert NULL für alle Datentypen. Der Wert NULL für ein Attribut sagt aus, dass für dieses Attribut kein Wert bekannt ist. Er ist auf keinen Fall mit dem Wert 0 für numerische Typen oder dem leeren String für Zeichenketten zu verwechseln. Eine Besonderheit ist, dass der Wert NULL von sich selbst verschieden ist, dh. es gilt NULL NULL 5. 2 aus historischen Gründen unterscheiden sich die Datentypen der Hersteller zum Teil. 3 Character Large Object 4 Binary Large Object 5 Dies bedeutet insbesondere auch, dass die Bedingung A = A nur für Attributwerte ungleich NULL wahr ist.

1.5 Syntax 5 Wie bereits erwähnt, findet man die hier beschrieben Datentypen nicht unbedingt so in den konkreten Datenbanksystemen wieder, sondern diese weichen von der Namensgebung und/oder der Semantik oft etwas vom Standard ab. Eine Abbildung der im SQL3 Standard vorgeschlagenen Datentypen auf konkreten Datentypen einer Reihe populärer Datenbanksysteme findet sich in [KK01]. In SQL3 wurde weiterhin festgelegt, dass sich aus den vorgegebenen Datentypen eigene (auch strukturierte) Datentypen ableiten lassen. Diese können dann ebenso wie die vom System vorgegebenen Datentypen verwendet werden. Auf diesen Punkt soll hier jedoch nicht weiter eingegangen werden, der interessierte Leser sei auf [Tür03] verwiesen. 1.5 Syntax Die Syntax von SQL ist relativ einfach. Die Befehle der DML, DDL und DCL beginnen stets mit einem oder mehreren Schlüsselwörtern, welche den konkreten Befehl spezifizieren. Es können beliebige Einrückungen und Umbrüche innerhalb eines Befehls getätigt werden. Werden mehrere Befehle hintereinander geschrieben, so werden die einzelnen Befehle mit einen Strichpunkt (;) beendet. 1.5.1 Groß-/Kleinschreibung Schlüsselwörter können beliebig groß- oder kleingeschrieben werden. Genauso verhält es sich mit Bezeichnern für Tabellen 6, Indexe, Attributen, etc. 1.5.2 Literale Werte für Zeichenketten und Datumsangaben werden in einfache Hochkommas ( ), numerische Literale werden ohne Hochkommas geschrieben. Beispiel: insert into city (name, country, province, population) values ( Karlsruhe, D, Baden Württemberg, 277011) 1.5.3 Kommentare SQL kennt zwei Arten von Kommentaren. Zum einen gibt es die aus vielen anderen Sprachen bekannten Kommentarklammern /*... */, die Kommentare über mehrere Zeilen enthalten können. Beispiel: /* * Autor : Smiff * Version : 1.22 */ 6 Bei MySQL spielt die Groß-/Kleinschreibung z.t. eine Rolle, da die einzelnen Tabellen auf Dateien mit dem Namen der Tabelle abgebildet werden. Unterscheidet das zugrunde liegende Betriebssystemen zwischen Groß- und Kleinschreibung, so muss die Schreibweise konsistent sein.

6 1 SQL Weiterhin gibt es noch Kommentare, die nur bis ans Ende der aktuellen Zeile reichen. In SQL werden diese durch zwei hintereinander geschriebene Minuszeichen eingeleitet. Beispiel: -- ab hier kommt die Definition der Foreign Keys 1.6 Data Manipulation Language Im folgenden Abschnitt soll nun die Data Manipulation Language (DML) von SQL vorgestellt werden, d.h. der Teil, der sich mit Anfragen und Modifikationen an bestehenden Datenbanken beschäftigt. Die DML stellt die Umsetzung der Operationen der Relationenalgebra (Abschnitt 1.2.3) dar. Die verschiedenen Konzepte werden zuerst kurz abstrakt dargelegt und dann anschließend an einem oder mehreren Beispielen verdeutlicht. Die Beispiele setzen alle auf der Mondial-Datenbank [Mon99] auf, die unter der angegebenen URL für Trainings- und Lehrzwecke frei verfügbar ist. Bevor nun im Folgenden mit der Einführung in die DML begonnen wird, werden zuerst noch die im Rahmen der Beispiele benutzten Tabellen aus der Mondial-Datenbank vorgestellt. 1.6.1 Mondial Datenbank Die gesamte Mondial-Datenbank umfasst ca. 25 Tabellen, von denen hier aber nur wenige benötigt werden. In Abbildung 1.2 ist ein Ausschnitt des Abhängigkeitsschema der Mondial-Datenbank dargestellt. Die Kästen repräsentieren die Tabellen mit ihren Attributen. Bei unterstrichenen Attributen handelt es sich um Primärschlüssel, grau unterlegte Attribute stellen Fremdschlüssel dar. Abb. 1.2: Auszug aus Abhängigkeitsschema der Mondial-Datenbank

1.6 Data Manipulation Language 7 In der oberen Hälfte der Abbildung sieht man die Tabellen province, country und city und ihre Beziehungen zueinander. Der Primärschlüssel der Tabelle city besteht aus den drei Attributen name, province und country. Teile des Primärschlüssels (province, country) bilden weiterhin einen Fremdschlüssel auf die Provinz, in der sich die Stadt befindet. Dadurch wird eine 1 : n- Beziehung 7 zwischen einer Provinz und den darin liegenden Städten realisiert. Die übrigen Attribute geben die Einwohnerzahl (population) und die Geo-Koordinaten der Stadt (longitude, latitude) an. Der Primärschlüssel der Tabelle province besteht aus den Attributen name und country. country wiederum ist ein Fremdschlüssel auf das Schlüsselattribut code der Tabelle country und stellt den Bezug zwischen einer Provinz und dem zugehörigen Land her. Tabelle country besitzt neben dem Primärschlüssel code einen dreiteiligen Fremdschlüssel (code, capital, province), der auf den entsprechenden Hauptstadt-Datensatz in der Tabelle city verweist. Hierbei handelt es sich um die Umsetzung einer 1 : 1- Beziehung 8 zwischen einem Land und der zugehörigen Hauptstadt. In der unteren Hälfte des Abhängigkeitsschemas sieht man die beiden Tabellen river und geo_river. Tabelle river benutzt den Namen des Flusses (Attribut name) als Primärschlüssel. Die nächsten 3 Attribute (river, lake, sea) sind jeweils Fremdschlüssel und geben an, ob der Fluss in einen anderen Fluss (river), einen See (lake) oder in ein Meer (sea) mündet. Die Beziehung zwischen Provinzen und Flüssen wird über die Tabelle geo_river hergestellt, die hier ausschnittsweise wiedergegeben wird: River Country Province......... Donau RO Braila Donau RO Tulcea Donau D Baden Württemberg Donau A Lower Austria Drin AL Albania Elbe D Niedersachsen Elbe D Hamburg Fulda D Hessen Gambia WAG Gambia Gambia SN Tambacounda......... 447 Datensätze Hierbei handelt es sich um eine so genannte Beziehungstabelle. Beziehungstabellen werden in relationalen Datenbanken zur Modellierung von n : m- Beziehungen eingesetzt. 7 Jede Stadt gehört zu genau einer Provinz, umgekehrt kann eine Provinz mehrere Städte haben. 8 Dass eine Stadt maximal Hauptstadt eines Landes sein kann, wird durch die Formulierung eines unique-constraints (siehe Abschnitt 1.7.1) erreicht.

8 1 SQL Während sich 1 : 1- und 1 : n-beziehungen, wie zuvor gesehen, problemlos durch die Hinzunahme eines Fremdschlüssels 9 modellieren lassen, wird bei n : m-beziehungen eine zusätzliche Tabelle benötigt. Eine Beziehungstabelle besteht aus mindestens zwei Fremdschlüsseln, die auf die in Beziehung stehenden Tabellen verweisen. Konkret besteht die Tabelle geo_river aus einem Fremdschlüssel auf den betreffenden Fluss (Attribut river) und einem Fremdschlüssel auf die Provinz (Attribute province, country) die der Fluss durchfließt. Somit ist es möglich, dass ein Fluss mehrere Provinzen durchfließen kann, umgekehrt kann eine Provinz auch von mehreren Flüssen durchflossen werden. Ein Auszug aus Tabelle geo_river ist in nachfolgender Tabelle dargestellt. Im Folgenden sollen nun anhand obiger Tabellen die DML Befehle vorgestellt werden. Hinweis. Es wird empfohlen, die Beispiele an einem realen System nachzuvollziehen und mit ihnen etwas zu spielen. Dazu gibt es auf der Webseite [Smi05] einen web basierten Zugang zu einer Mondial-Datenbank, einschließlich einer Sammlung aller im Folgenden vorgestellten Statements 10. Damit lassen sich die Anfragen sofort am Datenbestand nachvollziehen und variieren, ohne lokal ein Datenbanksystem installieren zu müssen. 1.6.2 Select-Statement Als erstes soll nun im Folgenden das select-statement eingeführt werden. Es ist für die Extraktion von Informationen aus der Datenbank zuständig. Das einfachste select-statement ist die Ausgabe aller Daten einer Tabelle. Dazu wird in der select-klausel mittels dem Wildcardzeichen * signalisiert, dass alle Spalten ausgegeben werden sollen. In der from-klausel wird die Tabelle angegeben. Das Ergebnis sind dann alle Datensätze, die sich in der betreffenden Tabelle befinden. select * from river Name River Lake Sea Length............... Mekong South China Sea 4500 Orinoco Atlantic Ocean 2736 Werra Weser 292 Fulda Weser 218 Columbia River Pacific Ocean 1952............... 132 Datensätze Projektion. Sollen nicht alle Spalten einer Tabelle ausgegeben werden, so kann man in der select-klausel die Attribute festlegen, die ausgegeben werden sollen. 9 der Fremdschlüssel kommt in die Tabelle, deren Datensätze jeweils mit maximal einem anderen Datensatz in Beziehung stehen. 10 nur select-statement, Datenmanipulationen sind nicht erlaubt.

1.6 Data Manipulation Language 9 select name, capital from country name capital Albania Tirane Greece Athens Macedonia Skopje...... 195 Datensätze Sortierung. Soll die Ausgabe sortiert werden, so wird die order-klausel verwendet, welche ans Ende des select-statements angefügt wird. Die Klausel nimmt eine Liste von Spalten entgegen, nach denen dann sortiert werden soll. Wird mehr als ein Attribut angegeben, so erfolgt die Sortierung der Priorität nach absteigend von links nach rechts. Es können entweder Namen der Attribute nach denen sortiert werden soll angegeben werden oder es können Spaltennummern (beginnend bei 1) angegeben werden, die sich auf die Position der Attribute in der select-klausel beziehen. Standardmäßig wird aufsteigend (asc) sortiert, soll absteigend sortiert werden so ist (desc) hinter dem Attribut bzw. der Spaltennummer anzugeben. Im folgenden Beispiel werden der Name und die Länge der Flüsse aus Tabelle river absteigend sortiert nach der Länge der Flüsse ausgegeben. select name, length from river order by length desc name length Amazonas 6518 Jangtse-Kiang 6100 Parana 4700 Mekong 4500...... 132 Datensätze Bedingungen. Bisher wurden immer alle Datensätze einer Tabelle ausgegeben. Will man jedoch nur Datensätze, die eine bestimmte Bedingung erfüllen ausgeben, so benötigt man die where-klausel, welche die Formulierung von Bedingungen ermöglicht. Bedingungen werden auf den Attributen formuliert und können mit not, and, or zu komplexeren Bedingungen zusammengesetzt werden 11. Zusätzlich können Klammern eingesetzt werden, so dass sich beliebige Ausdrücke formulieren lassen. Als Operatoren stehen unter anderem die üblichen Verdächtigen (=, <> 12, <, <=, >, >=) zur Verfügung. Der Vergleich erfolgt entweder mit einem Literal oder einem anderen Attribut. Im folgenden Beispiel werden alle Flüsse ausgegeben, die in den Atlantischen Ozean (Literal Atlantic Ocean ) münden. 11 not hat dabei die höchste Bindungspriorität, gefolgt von and und or 12

10 1 SQL select name, sea, length from river where sea= Atlantic Ocean order by name name sea length Amazonas Atlantic Ocean 6518 Connecticut River Atlantic Ocean 660 Cuanza Atlantic Ocean Cunene Atlantic Ocean......... 19 Datensätze Eine weitere Möglichkeit ist die Formulierung von Bedingungen mittels Mustervergleich. Dazu gibt es in SQL die Operatoren like und not like. Die beiden Sonderzeichen % und _ stellen dabei so genannte Wildcards dar. % steht für eine beliebige Anzahl von Zeichen, _ steht für exakt ein Zeichen. Die Bedingung stadtname like %burg liefert beispielsweise alle Städte zurück, die auf burg enden, so z.b. Hamburg, Salzburg, Sankt Petersburg. Neuere Versionen einzelner Datenbanksysteme erlauben zudem die Suche mittels regulären Ausdrücken [Fri00], einer mächtigen Sprache zur Formulierung von Textmustern. Diese Funktionalität ist jedoch nicht standardisiert und soll hier auch nicht weiter vertieft werden. Weiterhin gibt es noch den Operator between, der zur Bereichsüberprüfung eingesetzt werden kann. Beispiel: einwohner between 1000 and 20000 gibt alle Datensätze zurück, deren Einwohnerzahl zwischen 1000 und 20000 Einwohner liegt. Um ein Attribut gegenüber eine Menge von Werten zu testen kann man entweder mehrere Bedingungen mittels or verbinden oder den in-operator benutzen. Beispiel: code in ( F, ES, I, GR ) gibt alle Länder zurück, deren code entweder F, ES, I oder GR ist. Der in-operator wird uns später auch noch bei den Subqueries (Seite 14) begegnen, wo statt der Liste von Literalen ein vollständiges select-statement stehen kann. Umgang mit NULL. Eine besondere Bedeutung spielt, wie in Abschnitt 1.4 bereits angesprochen, der Attributwert NULL. Da NULL auch von sich selbst verschieden ist, führt die Formulierung folgender Bedingung immer zu FALSE: attributname = NULL Aus diesem Grund stellt SQL zwei spezielle Operatoren zur Verfügung: is null : testet ob der Wert eines Attributs NULL ist. is not null : testet ob der Wert eines Attributs ungleich NULL ist. Das folgende Beispiel wählt alle Flüsse aus, die in einen See münden und länger als 1000 Kilometer sind.

1.6 Data Manipulation Language 11 select name,lake,length from river where lake is not null and length > 1000 name lake length Kura Caspian Sea 1364 Rhein Bodensee 1320 Volga Caspian Sea 3531 Amudarja Ozero Aral 1415......... 6 Datensätze Duplikatseliminierung. Je nach Anfrage ist es möglich, dass identische Zeilen im Ergebnis erscheinen. Wünscht man dies nicht, so kann dies durch Angabe des Schlüsselwortes distinct innerhalb der select-klausel unterbunden werden. So führt die nahe liegende Lösung auf die Frage nach allen Flüssen die Zuflüsse besitzen nicht zum gewünschten Ergebnis, da viele Flüsse mehrere Zuflüsse haben und somit in der Ergebnismenge mehrfach auftreten. select river from river where river is not null order by 1 river Amudarja Amur Amur Busira... 57 Datensätze Erst durch die Hinzunahme von distinct erscheint das erwünschte Ergebnis. select distinct river from river where river is not null order by 1 river Amudarja Amur Busira Dalaelv... 27 Datensätze Spaltenaliase. Sollen die Überschriften der Spalten verändert werden, so werden Spaltenaliase eingesetzt Spaltenaliase werden in der select-klausel hinter der jeweiligen Spalte und dem Schlüsselwort as angegeben. Das folgende Beispiel zeigt die Daten der Tabelle river mit deutschen Spaltenüberschriften. Der zweite Spaltenalias bestehen aus mehr als einem Bezeichner und muss deshalb in doppelten Anführungszeichen (") stehen.

12 1 SQL select name as Flussname, round(length/1.609) as "Länge (Meilen)" from river where length is not null order by 2 desc Flussname Länge (Meilen) Amazonas 4051 Jangtse-Kiang 3791 Parana 2921 Mekong 2797...... 90 Datensätze Man sieht weiterhin, dass es hiermit auch möglich ist, berechnete Spalten (Umrechnung des Wertes der Spalte length von Kilometer nach Meilen) 13 einen sinnvollen Namen zu geben. Die order-klausel gibt schließlich an, dass die Ausgabe absteigend nach der 2. Spalte sortiert erfolgen soll. Aggregatsfunktionen. SQL stellt eine Reihe von Funktionen zur Verfügung, welche als Eingabe eine Tupelmenge (Menge von Datensätzen oder Menge von Einzelwerten) erwarten, als Ausgabe jedoch nur einen einzigen Wert zurückliefern. Im Unterschied zu normalen Funktionen (siehe Tabelle 1.6.2) arbeiten diese Funktionen somit tupel übergreifend und werden deshalb als Aggregatsfunktionen bezeichnet. SQL kennt folgende Aggregatsfunktionen: count(<attributbezeichner>) bzw. count(*) : Zählt die Anzahl der Elemente in der übergebenen Menge und liefert deren Anzahl zurück. Es können entweder komplette Datensätze (symbolisiert durch *) oder einzelne Attribute (Angabe des Attributnamens) an die Funktion übergeben werden. Im Fall, dass count(...) mit einem Attributnamen aufgerufen wird ist wichtig zu wissen, dass nur Nicht-NULL Werte gezählt werden. Sollen keine Duplikate gezählt werden, so kann mit count(distinct...) vor dem Zählen eine Duplikatseleminierung durchgeführt werden. sum(<attributbezeichner>) : Summiert die einzelnen Werte der übergebenen Zahlenmenge auf. Das Attribut muss numerisch sein. avg(<attributbezeichner>) : Liefert den Durchschnitt der einzelnen Werte der übergebenen Zahlenmenge. Das Attribut muss numerisch sein. stddev(<attributbezeichner>) 14 : Liefert die Standardabweichung der einzelnen Werte der übergebenen Zahlenmenge. Das Attribut muss numerisch sein. min(<attributbezeichner>) : Liefert den kleinsten Wert der einzelnen Werte der übergebenen Wertemenge. max(<attributbezeichner>) : Liefert den größten Wert der einzelnen Werte der übergebenen Wertemenge. Das folgende Beispiel ermittelt die Länge des längsten Flusses: 13 Die Grundrechenarten (+,,,/) sowie die Funktion round(...) sind in SQL standardmäßig verfügbar. Eine Übersicht über weitere Funktionen findet sich in Tabelle 1.1 auf Seite 21. 14 Beim MS SQL-Server heißt diese Funktion stdev

1.6 Data Manipulation Language 13 select max(length) as Länge from river Länge 6518 1 Datensatz Gruppierungen. So wie die Aggregatsfunktionen im obigen Beispiel angewandt wurde, liefert sie für ein select-statement genau einen Datensatz zurück. Indem wir die Datensätze zuvor gruppieren, kann die Aggregatsfunktion auf jede Gruppe einzeln angewandt werden. Um eine Gruppierung durchzuführen, benötigt man die group by-klausel. Der Klausel folgt eine Liste von Attributen, nach denen gruppiert werden soll. Die Gruppierung erfolgt dann derart, dass alle Datensätzen, deren Werte bei den in der group by- Klausel spezifizierten Attributen übereinstimmen, zusammengefasst werden. Das folgende Beispiel in Abbildung 1.3 zählt für jeden Fluss in der Datenbank, wieviele Zuflüsse er hat. Dazu werden in einem ersten (internen 15 ) Schritt, alle Datensätze deren Werte in der Spalte river übereinstimmen in eine Gruppe zusammengefasst (Mitte). Anschließend wird dann für jede Gruppe gezählt, wieviele Datensätze in ihr existieren und diese Information, absteigend sortiert nach der Anzahl der gruppierten Datensätze sowie anschlisssend den Namen der Quellflüsse, ausgegeben (Rechts). Abb. 1.3: Gruppieren nach Flüssen mit Aggregation 15 die mittlere Ausgabe dient lediglich der Verdeutlichung der Gruppierung, wird aber nicht ausgegeben

14 1 SQL Bedingungen auf Aggregaten. Als nächstes sollen jetzt auf den Aggregaten Bedingungen formuliert werden. So sollen beispielsweise nur die Flüsse ausgegeben werden, die drei oder mehr Zuflüsse besitzen. Schaut man sich das obige SQL-Statement an, so erkennt man, dass dies nicht in der where-klausel passieren kann, da zum Zeitpunkt der Auswertung der where-klausel das Aggregat noch nicht errechnet ist, sondern hier nur entschieden wird, welche Datensätze überhaupt der Gruppierung zugeführt werden (nur solche die in der Spalte river einen Wert stehen haben). Aus diesem Grund existiert die having-klausel, welche es dann in einem nachgeschalteten Schritt erlaubt, Bedingungen auf den Ergebnissen von Aggregatsfunktionen zu formulieren. Im konkreten Beispiel sind das die Flüsse, für die die Spalte count(*) einen Wert größer zwei liefert, d.h. der Fluss drei oder mehr Zuflüsse hat. select river, count(*) as "Anzahl Zuflüsse" from river where river is not null group by river having count(*) > 2 order by 2 desc river Anzahl Zuflüsse Zaire 7 Ob 4 Nile 3 Kwa 3 White Nile 3 Zambezi 3 6 Datensätze Das Statement gleicht dem zuvor mit dem einzigen Unterschied, dass in der neu hinzugekommenen having-klausel eine Bedingung formuliert wurde, in der eine Aggregatsfunktion vorkommt. Subquery. Mittels einer Subquery können mehrere SQL-Statements kombiniert werden. Dazu wird in der where-klausel einfach statt eines Literals ein in Klammer stehendes select-statement eingesetzt. So kann die Frage nach allen Flüssen, die eine überdurchschnittliche Länge haben, wie folgt beantwortet werden: name length Amazonas 6518 Jangtse-Kiang 6100 Parana 4700 Mekong 4500...... 34 Datensätze Zuerst wird hierbei das Ergebnis des inneren, grau unterlegten, select-statement ermittelt. Anschließend wird dann die äußere Anfrage mit dem Ergebnis der inneren Anfrage ausgeführt. Bei der Benutzung der Operatoren <, >, =, <> ist es notwendig, dass das innere Statement genau einen Datensatz zurückliefert. Dies ist oft dann der Fall, wenn eine

1.6 Data Manipulation Language 15 Bedingung auf dem Primärschlüssel formuliert wird, bzw. wenn wie im Beispiel eine Aggregatsfunktion eingesetzt wird. Eine andere Möglichkeit besteht darin, ein Attribut gegenüber einer Menge von Werten zu vergleichen. Dazu wird der auf Seite 10 eingeführte in-operator benutzt. Statt der konstanten Literale wird einfach ein select-statement in die Klammer geschrieben. Das folgende Beispiel gibt alle Ländernamen aus, die von der Donau durchflossen werden. Dazu werden in einem ersten Schritt innerhalb der grau unterlegten Subquery alle Ländercodes extrahiert, durch welche die Donau entsprechend den Informationen aus der Tabelle geo_river (siehe Seite 7) fließt. Das äußere Statement nimmt diese Menge entgegen und gibt dann für alle Länder deren code sich in der von der Subquery ermittelten Menge befinden, den Landesnamen (name) aus. name Austria Bulgaria Germany Hungary... 7 Datensätze Im obigen Beispiel konnte die innere Abfrage unabhängig von der äußeren Abfrage ausgeführt werden, man spricht in diesem Fall von einer unkorrelierten Subquery. Es ist jedoch auch möglich, die innere Abfrage mit der Äußeren zu verzahnen. Dies wird dadurch realisiert, indem in der where-klausel der inneren Anfrage auf ein Attribut der äußeren Anfrage zugegriffen wird. In diesem Fall kann die innere Anfrage nicht mehr unabhängig von der Äußeren ausgeführt werden, sondern muss für jedes Tupel der äußeren Anfrage erneut ausgeführt werden. Man spricht in diesem Fall von einer korrelierten oder verzahnt geschachtelten Anfrage [HS00]. Das folgende Beispiel zeigt eine derart verzahnte Abfrage. Die Anfrage soll alle Flüsse zurückliefern, die durch mehr als 3 Länder fließen. name Amazonas Amudarja Dnepr Donau... 12 Datensätze Die zusätztlich hier neu eingeführte Punkt -Notation dient zur eindeutigen Unterscheidung der Attribute in den verschiedenen Tabellen. So gibt es beispielsweise sowohl in der Tabelle river, als auch in der Tabelle country ein Attribut name, die durch Voranstellen des Tabellennamens auseinander gehalten werden können.

16 1 SQL Es gilt allgemein als guter Stil mit der Punktnotation zu arbeiten, da man dadurch schneller erkennen kann, zu welcher Tabelle das jeweilige Attribut gehört. Die Notation wird auch von allen relationalen Datenbanksystemen unterstützt. Das eigentlich Interessante an der grau unterlegten Subquery befindet sich in der where- Klausel, die lautet: where geo_river.river = river.name In der Subquery ist das Attribut river.name jedoch unbekannt, da in der from-klausel nur die Tabelle geo_river eingebunden wird. river.name stammt jedoch aus der äußeren Query (durch Pfeil angedeutet), in der die Tabelle river eingebunden ist und ist somit deren Attribute auch in der inneren Anfrage sichtbar sind. Die Abfrage läuft nun wie folgt ab: 1. Die äußere Anfrage untersucht den ersten Datensatz, konkret einen Fluss. 2. Der Name des Flusses (Attribut river.name) wird jetzt an die Subquery übergeben, die daraufhin untersucht, wie viele Datensätze mit unterschiedlichem Landescode (count(distinct geo_river.country)) für diesen Flussnamen existieren. 3. Die Anzahl der Datensätze wird an die äußere Anfrage zurückgegeben und in der where-klausel mit dem Literal 3 verglichen. Ist der zurück gelieferte Wert größer oder gleich, so wird der Name des Flusses ausgegeben. 4. Anschließend wird von der äußeren Anfrage der nächste Datensatz gelesen und es wird mit Schritt (2) fortgefahren. Ähnlich wie der in-operator funktioniert der exists -Operator. Im Unterschied zum in-operator wird der exists-operator ohne Attribut und Operator eingesetzt. Er überprüft lediglich, ob eine Subquery mindestens einen Datensatz zurückliefert. Ist das der Fall liefert exists TRUE zurück, andernfalls FALSE. Der exists-operator wird fast ausschließlich mit korrelierten Subqueries eingesetzt. Beispielsweise lässt sich die letzte Anfrage nach den Flüssen, die durch drei oder mehr Länder fließen auch mittels des exists-operators und einer having-klausel in der grau unterlegten korrelierten Unterabfrage formulieren: name Amazonas Amudarja Dnepr Donau... 12 Datensätze Mengenoperationen. SQL stellt eine Reihe von Mengenoperationen zur Verfügung, mittels denen die Ergebnisse von zwei select-statement kombiniert werden können. Im einzelnen handelt es sich um folgende Operationen: union : Vereinigung der Tupel beider Anfragen.

1.6 Data Manipulation Language 17 except : Es werden alle Tupel des ersten select-statement ausgegeben, die nicht im Ergebnis des zweiten select-statement stehen 16. intersect : Es werden alle Tupel ausgegeben, die sich sowohl im Ergebnis der erstenals auch der zweiten SQL-Anweisung befinden 17. Diese Operationen arbeiten als reine Mengenoperationen, d.h. es findet jeweils eine Duplikatseliminierung der Ergebnisrelation statt. Sollen Duplikate erhalten bleiben, so muss man auf die Operationen union all, except all 18 bzw. intersect all 18 zurückzugreifen. Bei den Operationen ist darauf zu achten, dass die Tupel der beiden Ergebnismengen eine kompatible Struktur besitzen. Kompatibel heißt in diesem Fall, dass die Anzahl Spalten in den beiden select-klauseln identisch sein muss und die jeweiligen Datentypen der Attribute kompatibel 19 sind. Das folgende Beispiel vereinigt alle Seen und Meere, die Zuflüsse haben. (select sea as "Gewässer" from river where sea is not null) union (select lake as "Gewässer" from river where lake is not null) order by 1 Joins. Bisher kamen die angezeigten Ergebnisse stets aus einer Tabelle. Zwar kann mithilfe von Subqueries auf Daten mehrerer Tabellen zugegriffen werden, Anfragen wie: Gib alle Flüsse mit ihren Längen und den Namen der durchflossenen Ländern aus konnten bisher aber nicht beantwortet werden, da hierbei die benötigten anzuzeigenden Daten aus verschiedenen Tabellen stammen. Mit Hilfe von Joins können Daten aus verschiedenen Tabellen miteinander in Bezug gesetzt und zusammen ausgegeben werden. Betrachten wir noch einmal die Daten aus den Tabellen river, geo_river und country. Die Tabelle river enthält die Flussdaten, während die Tabelle country Daten zu den einzelnen Ländern bereithält. Die beiden Tabellen haben keinerlei Bezug zueinander. Der Bezug kann aber über die Tabelle geo_river hergestellt werden. Die Spalte geo_river.river ist ein Fremdschlüssel auf den Primärschlüssel der Tabelle river (Attribut name), während das Attribut geo_river.country ein Fremdschlüssel auf den Primärschlüssel der Tabelle country (Attribut code) darstellt. Abbildung 1.4 verdeutlicht diesen Zusammenhang graphisch. Will man beispielsweise wissen, durch welche Länder die einzelnen Flüsse fließen, so muss man die beiden Fremdschlüsselbeziehung der Tabelle geo_river verfolgen und dabei die Schlüssel-/Fremdschlüsselattribute jeweils gleichsetzen. Konkret muss im obigen Beispiel gelten: 16 Oracle, PostgreSQL nicht beim MS SQL-Server und MySQL 17 nicht beim SQL-Server und MySQL 18 nur DB2 19 Numerische Datentypen sind untereinander kompatibel und alle zeichenkettenbasierten Datentypen sind ebenfalls untereinander kompatibel

18 1 SQL river.name = geo_river.river (Linien links in Abbildung 1.4) und geo_river.country = country.code (Linien rechts in Abbildung 1.4) Abb. 1.4: Beziehung zwischen Flüssen und Ländern Die im SQL-89 Standard festgelegte Syntax für einen Join (Theta -Notation), lässt sich dann auch relativ einfach aus obiger Überlegung ableiten, indem in der from-klausel einfach alle Tabellen aufgeführt werden, die für die Anfrage relevant sind und in der where-klausel die Bedingungen, welche zwischen den Schlüsseln-/Fremdschlüsseln gelten müssen, formuliert werden. So lautet die Anfrage, die für alle Flüsse über 2000 Kilometer Länge, den Namen, die Länge, sowie die Namen der durchflossenen Länder ausgeben soll, wie folgt: select distinct river.name as Fluss, river.length as Länge, country.name as Land from country, river, geo_river where river.name = geo_river.river and geo_river.country=country.code and river.length > 2000 order by 2 desc Fluss Länge Land Amazonas 6518 Brazil Amazonas 6518 Colombia Amazonas 6518 Peru Jangtse-Kiang 6100 China Parana 4700 Argentina......... 49 Datensätze distinct muss in diesem Fall benutzt werden, da in der Tabelle geo_river die Beziehungen zu den einzelnen Provinzen angegeben sind, hier aber nur die Länder interessieren. Ein Nachteil der Join-Syntax im SQL-89 Standard ist, dass man auf den ersten Blick nicht erkennen kann, was Schlüssel-/Fremdschlüsselvergleiche sind und wobei es sich um echte Bedingungen (fluss.laenge > 2000) handelt.

1.6 Data Manipulation Language 19 Aus diesem Grund wurde im SQL-2 Standard von 1992 eine etwas andere Notation für Joins vorgeschlagen, die so genannte ANSI -Notation. Neu bei der ANSI-Notation ist die join-klausel. Die Join Klausel tritt nach einer from- oder join-klausel auf 20, erwartet einen Tabellennamen und erlaubt anschließend (nach dem Schlüsselwort on) die Formulierung einer oder mehrerer Schlüssel- /Fremdschlüsselbedingungen für die zuvor angegebenen Tabellen. So lautet etwa die zuvor gestellte Anfrage in ANSI-Notation: select distinct river.name as Fluss, river.length as Länge, country.name as Land from country join geo_river on country.code=geo_river.country join river on geo_river.river = river.name where river.length > 2000 order by 2 desc Fluss Länge Land Amazonas 6518 Brazil Amazonas 6518 Colombia Amazonas 6518 Peru Jangtse-Kiang 6100 China Parana 4700 Argentina......... 49 Datensätze Bei dieser Notation wird die Trennung zwischen der eigentlichen Bedingung und den Schlüssel-/Fremdschlüsselbedingungen im Anschluss an die beiden join-klauseln deutlich. Neben dem klassischen Join mit Schlüssel-/Fremdschlüsselbedingung unterstützen die Datenbanken noch eine Reihe weitere Arten von Joins, die im Folgenden vorgestellt werden sollen. Cross Join (Kartesisches Produkt): Jeder Datensatz der linken Tabelle (A) wird mit jedem Datensatz der rechten Tabelle (B) kombiniert. Das Ergebnis ist eine Ergebnistabelle mit n-zeilen 21 und m-spalten 22. Der Cross-Join kommt in seiner Reinform relativ selten vor Er entspricht dem klassischen Join ohne Formulierung von Schlüssel-/Fremdschlüsselbedingungen. Die folgende Abbildung zeigt exemplarisch die Konstruktion des kartesischen Produktes aus zwei Tabellen. Abb. 1.5: Kartesisches Produkt von 2 Tabellen 20 Die join-klausel kann mehrfach auftreten, die erste join-klausel folgt jedoch immer der from-klausel. 21 n = Anzahl_Datenstze(A) Anzahl_Datenstze(B) 22 m = Anzahl_Attribute(A)+Anzahl_Attribute(B)

20 1 SQL Left Outer Join: Wie ein normaler Join, bei dem zusätzlich aber auch noch alle die Datensätze aus der linken 23 Tabelle ausgegeben werden 24, für die es auf der rechten Seite keine passenden Datensätze gibt. Die Spalten aus der rechten Tabelle enthalten dann im Ergebnis NULL Werte. Ein Beispiel für einen Outer-Join ist folgende Anfrage: Gib alle Länder zusammen mit ihren Flüssen aus select distinct country.name, geo_river.river from country left join geo_river on country.code=geo_river.country order by country.name, geo_river.river name river...... Albania White Drin Algeria Andorra Angola Casai...... 319 Datensätze Man kann sehen, dass Algerien und Andorra im Ergebnis auftauchen, obwohl für sie keine Flüsse in der Datenbank hinterlegt sind. Right Outer Join: Wie ein normaler Join, bei dem zusätzlich aber auch noch alle die Datensätze aus der rechten Tabelle ausgegeben werden 24 für die es auf der linken Seite keine passenden Datensätze gibt. Die Spalten aus der linken Tabelle enthalten dann im Ergebnis NULL Werte. Full Outer Join: Wie ein normaler Join, bei dem zusätzlich alle Datensätze sowohl aus der linken- als auch der rechten Tabelle ausgegeben für die es keine passenden Datensätze gibt. Die Spalten aus der linken bzw. rechten Tabelle enthalten dann im Ergebnis NULL Werte. Self Join: Wie ein normaler Join, allerdings wird zweimal die selbe Tabelle genutzt. Ein Beispiel dazu findet sich auf Seite 21. Aliasnamen für Tabellen. Esgibt in SQL die Möglichkeit Aliasnamen für Tabellen zu vergeben. Aliasnamen werden in der from- und join-klausel durch Anhängen des Aliasnamen direkt hinter den Tabellennamen vergeben. Anschließend kann im Statement der Aliasname anstelle des Tabellennamens verwendet werden. Notation: <tabellenname> <aliasname> Ein Vorteil liegt darin, dass man im Allgemeinen kurze und/oder aussagekräftige Aliasnamen vergeben kann und so zu einer kompakteren und übersichtlicheren Schreibweise bei Benutzung der Punkt-Notation kommt. Es gibt jedoch auch Situation, in der die Benutzung von Aliasen zwingend notwendig ist. Beispielsweise, wenn für alle Städte der USA Namensvettern in anderen Ländern gesucht werden sollen. Die benötigten Informationen liegen zwar alle in der Tabelle city. Allerdings ist es nicht so einfach die Anfrage zu formulieren, da die where-klausel es lediglich erlaubt Bedingungen auf Datensatzebene 25 zu formulieren. Um zum Ziel zu 23 im select-statement zuerst genannten Tabelle 24 sofern sie eine eventuell zusätzlich angegebene where-klausel erfüllen. 25 d.h. es wird zu einem Zeitpunkt genau ein Datensatz untersucht.

1.6 Data Manipulation Language 21 kommen muss man die Tabelle city mit sich selber vergleichen, d.h. es muss für jeden Datensatz aus der Tabelle city untersucht werden, ob es einen weiteren Datensatz in der selben Tabelle gibt, der den gleichen Namen (Attribut name) aber eine andere Länderkennung (Attribut country) hat. Das komplette Statement lautet dann folgendermaßen: select c1.name, c2.country from city c1 join city c2 on c1.name=c2.name where c1.country <> c2.country and c1.country= USA order by 1,2 name country Albany AUS Alexandria ET Alexandria RO Birmingham GB...... 18 Datensätze Funktionen. SQL definiert eine Reihe von Funktionen die im Rahmen der DML Statements eingesetzt werden können. So gibt es numerische, zeichenkettenbasierte Funktionen, ebenso wie eine Reihe von Konvertierungs- und Datumsfunktionen. Die Funktionen können in der select-, where-, order- und having-klausel eingesetzt werden. Da im Bereich der Funktionen noch etwas Wildwuchs in Bezug auf Standardisierung herrscht, sollen in Tabelle 1.1 lediglich einige exemplarische Funktionen aufgezählt werden, ohne jedoch auf deren genaue Syntax-/Aufrufkonventionen einzugehen. Der Leser sei an dieser Stelle auf die Literatur des konkreten Datenbanksystems verwiesen um einen umfassenden Überblick über die dort implementierten Funktionen zu erhalten. Tabelle 1.1: Funktionen in SQL Kategorie Vertreter Numerische Funktionen Trigonometrische Funktionen sin(...), cos(...), tan(...), asin(...), acos(...), atan(...),... Rundungsfunktionen round(...), ceil(...), floor(...),... Logarithmische- und Exponentialfunktionen ln(...), log(...), exp(...),... Potenz- und Wurzelfunktionen sqrt(...), power(...), pow(...),... sonstige numerische Funktionen sign(...), abs(...),... Zeichenketten basierte Funktionen ASCII Funtionen ascii(...), ord(...), char(...),... Groß-/Kleinschreibung upper(...), lower(...), initcap(...),... Leerzeichen am Beginn/Ende der Zeichenkette entfernen trim(...), ltrim(...), rtrim(...),... Zeichenketten durchsuchen/-ersetzen substr(...), instr(...), position(...), replace(...), patindex(...), translate(...),... sonstige Zeichenkettenfunktion concat(...), encrypt(...), format(...), length(...), left(...),...

22 1 SQL Kategorie Datumsfunktionen Vertreter Datumsinformationen: day(...), month(...), year(...), curdate(...), sysdate(), get_date(),... Konvertierungsfunktionen Zeichenkette -> Datum/Zeit to_date(...), extract(...),... Zeichenkette -> Zahl to_number(...), extract(...),... Unterabfragen/geschachtelte Ausdrücke. Auf Seite 3 wurde beschrieben, dass das Ergebnis einer relationalen Operationen stets wieder eine Relation ist, was insbesondere auch die Formulierung geschachtelter Anfragen erlaubt. Übertragen auf SQL bedeutet dies, dass in der from-klausel auch ein select-statement stehen kann. Einschränkend muss jedoch gesagt werden, dass an dieser Stelle keine korrelierten Abfragen (siehe Seite 15) erlaubt sind, d.h. das select-statement in der from-klausel darf keine Attribute aus der äußeren Query verwenden. Die Anfrage im folgenden Beispiel gibt alle Länder aus, deren Anteil der Stadtbevölkerung mindestens 50% der Gesamtbevölkerung beträgt. Dazu wird ein Join zwischen der Tabelle country und dem in Klammer stehenden select-statement (Tabellenalias u) formuliert. name ratio Liechtenstein 0.89 Singapore 0.75 Australia 0.67 Qatar 0.61 South Korea 0.59...... 8 Datensätze Das in der join-klausel stehende select-statement liefert pro Land (Spalte country) die berechnete Summe aller Einwohner der Städte (Spaltenalias population) zurück. Dieses Ergebnis wird dann mittels des Joins mit der Tabelle country um den ausgeschriebenen Landesnamen (Attribut country.name) ergänzt und nur die Länder ausgegeben, deren Anteil der Stadtbevölkerung (u.population) an der Gesamtbevölkerung (Spalte country.population) bei über 50% liegt. Diese Art von Anfrage wird auch als Instant View 26 bezeichnet. Weiterhin ist es auch möglich, dass ein select-statement in der select-, orderoder where-klausel auftritt. Im Unterschied zum vorherigen Fall sind hierbei auch korrelierte Subqueries erlaubt, allerdings muss das Statement genau einen Wert zurückliefern. So kann die letzte Anfrage nach allen Ländern mit mehr als 50% Stadtbevölkerung auch folgendermaßen formuliert werden: 26 Ein View ist eine virtuelle, auf einer Anfrage basierenden Tabelle und wird auf Seite 29 vorgestellt.

1.6 Data Manipulation Language 23 name ratio Liechtenstein 0.89 Singapore 0.75 Australia 0.67 Qatar 0.61 South Korea 0.59 United Kingdom 0.56 Antigua and Barbuda 0.55 Bahamas 0.54 8 Datensätze Das korrelierte Subquery in der select-klausel summiert dabei alle Einwohner in den Städten des aktuellen Landes (c.code) auf. Zur Formulierung der Bedingung, dass nur die Länder ausgegeben werden sollen, deren Anteil bei über 50% liegt, wird das in der select-klausel stehende select-statement in der where-klausel wiederholt 27. Soweit zu den verschiedenen, auf den Operationen der Relationenalgebra basierenden, Varianten des select-statement. In den folgenden drei Abschnitten sollen jetzt, ebenfalls auf Basis der Mondial-Datenbank, die insert-, update- und delete-statements vorgestellt werden. 1.6.3 Insert-Statement Das insert-statement erlaubt das Einfügen von Tupeln in eine Tabelle. Es stehen zwei Varianten zur Auswahl: insert into <tabellenname> (<attributliste>) values (<werteliste>) Bei dieser ersten Variante wird genau ein Datensatz in die angegebene Tabelle eingetragen. Die Attributliste beinhaltet dabei Attribute aus der angegebenen Tabelle. Es ist möglich weniger Attribute anzugeben, als für die Tabelle definiert worden sind 28. Wichtig ist hierbei, dass die Anzahl der hinter der insert-klausel stehenden Attribute identisch ist mit der Anzahl der Werte in der values-klausel und die Datentypen übereinsteimmen. Das folgende Beispiel zeigt den Eintrag der Stadt Karlsruhe in die Tabelle city. insert into city (name, country, province, population) values ( Karlsruhe, D, Baden Württemberg, 277011) Es ist jedoch auch möglich, mehrere Datensätze mittels einem insert-statement einzutragen. Dazu wird das insert-statement mit einem select-statement kombiniert. Die sich im select-statement qualifizierenden Datensätze werden dann in die im 27 das geschachtelte select-statement wird aber deshalb nicht mehrfach ausgeführt, sondern der Optimierer des Datenbanksystems erkennt, dass die Anfrage in der select-klausel und where-klausel identisch sind und führt sie deshalb nur einmal aus 28 Es können alle die Attribute weggelassen werden, die bei der Definition der Tabelle (siehe Seite 27) nicht als NOT NULL definiert wurden.

24 1 SQL insert-statement angegebene Tabelle eingetragen. Hierbei müssen die in der insert- Klausel angegebenen Attribute in Anzahl und Datentyp mit den Attributen des select- Statement übereinstimmen. insert into <tabellenname> (<attributliste>) (<select-anweisung>) Das folgende Beispiel trägt alle Datensätze aus der Tabelle terra_stadt 29 in die Tabelle city ein. insert into city (name, country, province, population, longitude, latitude) (select name, l_id, lt_id, einwohner, laenge, breite from terra_stadt) 1.6.4 Update-Statement Das update-statement dient dazu, Datensätze die sich bereits in einer Tabelle befinden zu modifizieren. Dabei können ein oder mehrere Datensätze auf einmal modifiziert werden. Die Syntax ist wie folgt: update <tabellenname> set <attribut1>=<wert1> [,<attribut2>=<wert2>]... where <bedingungen> Die Bedingungen entsprechen denen der where-klausel des select-statement. So setzt das folgende Statement die Koordinaten der Stadt Karlsruhe auf (8.4, 49.0): update city set longitude=8.4, latitude=49.0 where country= D and province= Baden Württemberg and name= Karlsruhe Neben Literalen können auch Berechnungen oder korrelierte Subqueries (die genau einen Wert zurückliefern) eingesetzt werden. So erhöht das folgende Beispiel die Einwohnerzahl aller italienischen Städte um 5%: update city set population = round(population*1.05) where country= I 29 Die Terra-Datenbank [DR90] wurde am Institut für Programmstrukturen und Datenorganisation der Universität Karlsruhe entwickelt und dort im Datenbankpraktikum eingesetzt. Die Terra- Datenbank diente der Mondial-Datenbank als Vorbild und z.t auch als Datenquelle [Mon99].