PostgreSQL hat eine Vielzahl an Datentypen, die hier (nicht vollständig) tabellarisch dargestellt werden. Die im Detail hier nachgelesen werden können.
CREATE TABLE
Anlegen von Tabellen inkl. der Möglichkeit Integritätsregeln zu definieren
ÀLTER TABLE
Verändern von Tabellen, wie zum Beispiel das Hinzufüge von Attributen, Löschen von Spalten (DROP COLUMN
), Ändern von Datentypen der definierten Attribute:
ALTER TABLE professoren
ALTER COLUMN name
TYPE varchar(50);
DROP TABLE
Löschen von Tabellen
Projektionen können mittels ORDER BY
sortiert werden. Dabei kann optional angegeben werden ob diese auf- bzw. absteigend sortiert werden sollen:
ASC
: Aufsteigend sortieren (Standard)
DESC
: Absteigend sortieren
Beispiel:
Professoren-Tabelle geordnet nach Rang (Hauptkreterium für Sortierung) und Name (Nebenkriterium für Sortierung):
SELECT * FROM professoren
ORDER BY rang desc, name asc
pers_nr | name | rang | raum |
---|---|---|---|
2136 | Curie | C4 | 36 |
2137 | Kant | C4 | 7 |
2134 | Augustinus | C3 | 309 |
2133 | Popper | C3 | 52 |
Aggregatfunktionen dienen dazu Tupelmengen mittels einer Operation auf einen Wert abzubilden.
Aggregationfunktionen, die auf Zahlen operieren:
Beispiele
Durchschnittliche Semesteranzahl:
SELECT avg(semester) FROM studenten;
Längste Studiendauer:
SELECT max(semester) FROM studenten;
Anazl aller Sutdenten:
SELECT count(*) FROM studenten;
Mit
$GROUP\ BY$ kann man Gruppen bilden, die mit Aggregatfunktionen ausgewertet werden können.
Beispiel
SELECT gelesen_von, sum(sws) FROM vorlesungen
GROUP BY gelesen_von;
Jede Gruppe wird nur durch ein einzelnes Tupel repräsentiert. Das heißt:
Alle in der Projektion verwendeten Attribute zur Erzeugung der Ergebnis-Relation müssen in der$GROUP\ BY$ -Klausel angegeben werden.
Nur so kann sichergestellt weredn, dass sich der Attributswert nicht innerhalb der Gruppe ändert.
Mit
Beispiel
SELECT gelesen_von, sum(sws) FROM vorlesungen
GROUP BY gelesen_von
HAVING avg(sws) >= 3;
$WHERE$ filtert die einzelnen Zeilen der Agregationsreltionen (bzw. kartesisches Produkt der Ausgangsrelation).$HAVING$ filtert die Gruppen - typischerweise bezüglich Aggregatsbedingungen.
Beispiel
SELECT gelesen_von, name, sum(sws) FROM vorlesungen, professoren
WHERE gelesen_von = pers_nr AND rang = 'C4'
GROUP BY gelesen_von, name HAVING avg(sws) >= 3;
Bisher wurde die Relationsalgebra genutzt, die prozedurale Berechnungsvorschrift (vgl. Operatorbäume).
Nun soll das Relationskalkül (deklarativ) basierend auf dem mathematischen Prädikatenkalkül erster Stufe, dem Existensquantor und Allquantor, genutzt werden.
Die zwei Ausprägungen des Relationenkalküls lauten:
- relationales Tupelkalkül
- relationales Domänenkalkül
Eine Anftage im Tupelkalkül hat die Form
$\{t\ |\ P(t)\}$ $t$: Tupelvariable $P$: Prädikat, welches erfüllt sein muss, damit $t$ Teil des Ergebnisses wird.Beispiel C4-Professoren
$\{\ p\ |\ p \in Professoren \wedge p.Rang = 'C4'\ \}$Studenten, die mindestens eine Vorlesung hören:
SELECT s.* FROM studenten s
WHERE EXISTS
(SELECT h.* FROM hoeren h
WHERE s.matr_nr = h.matr_nr);
Komplexeres Beispiel
Studenten, die mindestens eine Vorlesung von Sokrates hören:
SELECT s.* FROM studenten s WHERE EXISTS
(SELECT h.* FROM hoeren h WHERE
s.matr_nr = h.matr_nr AND EXISTS
(SELECT v.* FROM vorlesungen v WHERE
h.vorl_nr = v.vorl_nr AND EXISTS
(SELECT p.* FROM professoren p WHERE
p.pers_nr = v.gelesen_von AND
p.name = 'Sokrates')));
Wer hat alle vierstündigen Vorlesungen gehört:
In SQL können SELECT-Anweisungen auf verschiedenste Weise verbunden und geschachtelt werden.
Der SQL-Standard fordert, dass Unteranfragen geklammert werden.
Unteranfragen können dabei in allen drei Teilen einer SELECT-Anweisung stehen, dh. im SELECT-, FROM- und WHERE-Teil
Unkorreliert Unterfragen benutzen lediglich ihre "eigenen" Attribute.
Unkorrelierte Unteranfragen müssen nur einmal ausgewertet werden.
Beispiel
SELECT * FROM pruefen
WHERE note <= (SELECT avg(note) from pruefen);
Korrelierte Unteranfragen benutzen auch Attribute übergeordnerter Anfragen
Korrelierte Unteranfragen müssen i.A. für jedes Tupel der übergeordneten Anfrage ausgewertet werden ("nested-loop"-Semantik).
Beispiel
SELECT p.pers_nr, p.name, (SELECT sum(sws) FROM
vorlesungen v WHERE v.gelesen_von = p.pers_nr) AS
lehrbelastung FROM professoren p;
SELECT * from studenten s WHERE EXISTS
(SELECT p.* from professoren p
WHERE p.geb_datum > s.geb_datum);
VERSUS
SELECT * from studenten s
WHERE s.geb_datum < (SELECT
max(p.geb_datum) from professoren p);
- unkorellierte Unteranfragen sind effizienter
- Heutige Anfrageoptimierer sind i.A. nicht in der Lage korrelierte Unteranfragen selbst zu entkorrelieren
Korrelierte Unteranfragen sollen us Effizeinzgründen vermieden werden. Durch manuelle Umformulierungen lassen sich korrelierte Unteranfragen oft in unkorrelierte umformen, so lässt sich die Leistungsfähigkeit (performance) einer Datenbankanwendung erhöhen.
Bekannte Mengenoperatoren: UNION
, INTERSECT
, EXCEPT
Der Operator IN
testet auf Mengenmitgliedschaft (in WHERE-Klausel).
Komplementär zu IN
: NOT IN
Beispiel
-- Wähle alle Professoren, die keine Vorlesungen halten
SELECT name FROM professoren
WHERE pers_nr NOT IN
(SELECT gelesen_von FROM vorlesungen);
ANY
wird genutzt um zu testen, ob mindestens ein Element des Ergebnisses der Unteranfrage einen Vergleich erfüllt - enspricht dem IN
-Operator.
SELECT * FROM kunden WHERE rating > any(
SELECT rating FROM kunden
WHERE stadt = 'Berlin');
ALL
wird genutzt um zu testen, ob alle Elemente des Ergebnisses der Unteranfrage einen Vergleich erfüllen.
Keine All-Quantifizierung möglich: Finden der Studenten, die alle 4-stündigen Vorlesungen hören geht nicht.
SELECT name FROM studenten
WHERE semester >= all(
SELECT semester FROM studenten);