Bereitet Daten auf

SELECT H.land, COUNT(*) AS anzahl, AVG(P.preis) AS avg_preis
FROM hersteller H JOIN produkte P ON H.firma = p.hersteller
WHERE P.preis > 3
GROUP BY h.land
HAVING COUNT(*) < 5
ORDER BY COUNT(*)

Dummy-Tabelle DUAL

In einigen DBMS (Oracle, DB2, …) gibt es die Tabelle DUAL, die ist praktisch zum Rechnen und Ausprobieren von Funktionen, denn sie ist leer.

SELECT * FROM dual
dummy
-

Tabellen

FROM

Bestimmt auf welcher Tabelle die Anfrage ausgeführt wird

SELECT * FROM produkte

Kreuzprodukt

SELECT * FROM produkte, hersteller

Joins

-- Im WHERE-Prädikat
SELECT * FROM produkte, hersteller
WHERE produkte.hersteller = hersteller.firma
 
-- Äquivalent:
 
-- Mittels JOIN-Syntax
SELECT * FROM produkte JOIN hersteller
ON produkte.hersteller = hersteller.firma
 
-- Per Alias
SELECT * FROM produkte P JOIN hersteller H
ON P.hersteller = H.firma
 
-- USING kann verwendet werden,
-- wenn die Join-Spalten gleich heißen
SELECT P.*, B.sterne
FROM produkte P JOIN bewertungen B USING(produktnr)
 
-- Beide Spalten müssen übereinstimmen
SELECT P
FROM bewertungslikes l 
JOIN bewertungen B USING(kundennummer, produktnummer)
  • JOIN, LEFT JOIN, RIGHT JOIN, FULL JOIN

Joins verschachteln:

SELECT kunden.name, produkte.bezeichnung
FROM kunden
JOIN bewertungen ON kunden.kundennummer = bewertungen.kundennummer
JOIN produkte ON bewertungen.produktnummer = produkte.produktnummer

Selektion -

WHERE

  • Ternäre Logik: Möglichkeiten für Prädikate: true, false, null/unknown
  • Liefert die Zeilen, für die das WHERE-Prädikat true ergibt
SELECT * FROM produkte WHERE preis > 3
 
SELECT * FROM produkte WHERE preis >= 3 AND preis <= 9
-- Kurzschreibweise:
SELECT * FROM produkte WHERE preis BETWEEN 3 AND 9
-- Idee: Leere Herstellerspalten herausfinden
-- Funktioniert aber nicht!
-- hersteller = NULL ist nie true sondern höchstenfalls NULL!
-- Equals-Funktion: "Return NULL on NULL"
SELECT * FROM produkte WHERE herssteller = NULL

IS NULL - Überprüfen ob leer

SELECT * FROM produkte WHERE hersteller IS NULL

LIKE - Ähnlichkeit prüfen

  • Beliebig viele Zeichen: %
  • Genau ein Zeichen: _
  • Kombinierbar
SELECT * FROM produkte WHERE bezeichnung = 'Müsliriegel'
SELECT * FROM produkte WHERE bezeichnung LIKE 'M%'
SELECT * FROM produkte WHERE bezeichnung LIKE '%-%'
SELECT * FROM produkte WHERE bezeichnung LIKE 'M_sliriegel'

EXISTS -

  • Eingabe: Eine SELECT-Anfrage
  • Ausgabe:
    • TRUE, wenn die Anfrage mind. 1 Zeile liefert
    • FALSE, wenn die Anfrage die leere Menge liefert
-- Die Anfrage hier liefert Hersteller, von denen es Produkte gibt.
SELECT * FROM hersteller H
WHERE EXISTS 
	(SELECT * FROM produkte p WHERE p.hersteller = h.firma)

NOT EXISTS

-- Von welchen Herstellern gibt es keine Produkte?
SELECT * FROM hersteller H
WHERE NOT EXISTS 
	(SELECT * FROM produkte p WHERE p.hersteller = h.firma)

IN -

  • Eingabe: Ein Ausdruck und entweder eine Werteliste oder eine SELECT-Anfrage
  • Ausgabe:
    • TRUE, wenn der Ausdruck enthalten ist
    • FALSE, wenn der Ausdruck nicht enthalten ist
SELECT * FROM hersteller H
WHERE firma IN ('Holzkopf', 'Monsterfood')
 
-- Hersteller, von denen es Produkte gibt
SELECT * FROM hersteller H
WHERE firma IN (SELECT hersteller FROM produkte)
 
-- Hersteller, von denen es keine Produkte gibt
SELECT * FROM hersteller H
WHERE firma NOT IN
(SELECT hersteller FROM produkte WHERE hersteller IS NOT NULL)

Gruppieren

GROUP BY - Zeilen gruppieren

SELECT hersteller, COUNT(*), AVG(preis)
FROM produkte
GROUP BY hersteller

HAVING - Selektion nach der Gruppierung

  • Das HAVING kann nur Aggregatfunktionen vergleichen.
  • HAVING preis > 2 ist z.b. unzulässig
SELECT hersteller, COUNT(*)
FROM produkte
GROUP BY hersteller
HAVING COUNT(*) >= 2

COUNT - Anzahl

SELECT COUNT(*) FROM produkte
 
-- Count vom Spaltennamen zählt wie viele Zeilen in der Spalte 
-- einen Wert haben der nicht NULL ist
SELECT COUNT(hersteller) FROM produkte
 
-- Count mit Distinct sind die verschiedenen Werte
SELECT COUNT(DISTINCT hersteller) FROM produkte

SUM, AVG, MIN, MAX

-- Null-Werte werden nicht berücksichtigt
SELECT SUM(preis), AVG(preis), MIN(preis), MAX(preis) FROM produkte
-- Wenn alle Zeilen NULL sind oder keine 
-- Zeilen existieren, wird NULL zurückgegeben

Projektion -

SELECT

  • Mögliche Funktionen: round(zahl, nachkommastellen), upper(text), …
SELECT bezeichnung, preis, round(preis * 1.15, 2) AS preis_usd
FROM produkte

SELECT DISTINCT - Duplikateliminierung

SELECT DISTINCT preis FROM produkte

Sortieren und Begrenzen

ORDER BY - Sortieren

  • ASC ist der standardwert, kann man weglassen
  • NULLS LAST, NULLS FIRST
SELECT * 
FROM produkte 
ORDER BY preis ASC NULLS LAST, produktnr DESC

LIMIT - Begrenzen

SELECT *
FROM produkte
LIMIT 2
-- überspringe die ersten 5
OFFSET 5

Mengenoperationen

ALL

Bei Mengenoperationen ohne das Stichwort ALL wird nach UNION, INTERSECT und EXCEPT eine Duplikateliminierung vorgenommen
Syntax: UNION, UNION ALL, …

UNION - Zusammenführen -

-- Aus welchen Ländern sind unsere Kunden und Hersteller?
SELECT land FROM kunden
UNION
SELECT land FROM hersteller

INTERSECT - Schnittmenge -

-- In welchen Ländern gibt es Kunden und Hersteller?
SELECT land FROM kunden
INTERSECT
SELECT land FROM hersteller

EXCEPT - Minus -

-- In welchen Ländern gibt es Kunden, aber keine Hersteller?
SELECT land FROM kunden
EXCEPT
SELECT land FROM hersteller

Sub-Anfragen und CTEs

Common Table Expressions

  • WITH ... AS () definiert eine Tabelle, die später (auch mehrmals) wiederverwendet werden kann
  • Mehrere CTEs trennt man mit Komma: WITH ... AS (), ... AS (), ...
WITH monsterfoor_produkte AS
	(SELECT * FROM produkte WHERE hersteller = 'Monsterfood')
SELECT COUNT(*) FROM monsterfood_produkte
WHERE preis = (SELECT MAX(preis) FROM monsterfood_produkte)

Typumwandlungen

CAST

SELECT preis, CAST(preis AS INT), CAST(preis AS VARCHAR(50))
FROM produkte

Fallunterscheidungen

CASE WHEN

SELECT bezeichnung, preis,
CASE WHEN preis < 1 THEN 'billig'
WHEN preis < 5 THEN 'mittel'
ELSE 'teuer' END
FROM produkte
SELECT bezeichnung, preis,
CASE preis WHEN 0 THEN 'kostenlos' ELSE preis END
FROM produkte ORDER BY preis