ORDER BY spalte ASC -- aufsteigend, VoreinstellungORDER BY spalte DESC -- absteigendORDER BY a, b DESC -- mehrstufigLIMIT 10 -- höchstens 10 ZeilenLIMIT 10 OFFSET 20 -- Zeilen 21 bis 30
-- Neue Schreibweise (empfohlen)SELECT b.name, s.name FROM auftritt AS a JOIN band AS b ON b.band_id = a.band_id JOIN buehne AS s ON s.buehne_id = a.buehne_id;-- Alte Schreibweise, gleichwertigSELECT band.name, buehne.name FROM auftritt, band, buehne WHERE auftritt.band_id = band.band_id AND auftritt.buehne_id = buehne.buehne_id;-- Selbstverbund: Paare bildenSELECT p1.nachname, p2.nachname FROM person AS p1 JOIN person AS p2 ON p1.geburtsjahr = p2.geburtsjahr AND p1.person_id < p2.person_id;
Faustregel: eine Verbundbedingung weniger als Tabellen.
SELECT s.name, COUNT(*) AS anzahl FROM auftritt AS a JOIN buehne AS s ON s.buehne_id = a.buehne_id WHERE a.dauer_min >= 60 -- filtert Zeilen, vor dem Gruppieren GROUP BY s.nameHAVING COUNT(*) >= 3 -- filtert Gruppen, nach dem Gruppieren ORDER BY anzahl DESC;
Jede Spalte im SELECT muss im GROUP BY stehen oder in einer Aggregatfunktion.
-- als einzelner WertWHERE zuschauer > (SELECT AVG(zuschauer) FROM auftritt)-- als WertemengeWHERE band_id IN (SELECT band_id FROM auftritt WHERE buehne_id = 1)-- korreliert, in der SELECT-ListeSELECT b.name, (SELECT COUNT(*) FROM auftritt AS a WHERE a.band_id = b.band_id) AS n FROM band AS b;-- als Tabelle im FROM (Aliasname ist Pflicht)SELECT AVG(n) FROM (SELECT band_id, COUNT(*) AS n FROM auftritt GROUP BY band_id) AS x;
INSERT INTO tabelle (spalte1, spalte2) VALUES (wert1, wert2);INSERT INTO tabelle (spalte1) VALUES (a), (b), (c);UPDATE tabelle SET spalte = wert WHERE bedingung;DELETE FROM tabelle WHERE bedingung;
Ohne WHERE treffen UPDATE und DELETEjede Zeile. Schreibe die Bedingung zuerst als SELECT und sieh nach, was sie trifft.
graph LR
person -->|mitgliedschaft| band
band -->|band_genre| genre
band --> auftritt
buehne --> auftritt
besucherin --> ticket
besucherin -->|bewertung| auftritt
Der eingebaute Übersetzer lehnt diese Konstrukte ab; die Anweisung läuft dann gar nicht erst.
Nicht verwendbar
Ausweg
IS NULL, IS NOT NULL
– die Datenbanken enthalten deshalb keine fehlenden Werte
IFNULL, COALESCE
–
NOT IN (…)
Bedingung mit <> und AND umformulieren
EXISTS (…)
IN (Unterabfrage)
CASE WHEN … END
zwei Abfragen mit UNION
JOIN … USING (spalte)
JOIN … ON a.spalte = b.spalte
substr(…), CAST(…)
strftime; durch 1.0 teilen statt CAST
GROUP_CONCAT(…)
–
CREATE TABLE … AS SELECT
CREATE TABLE, danach INSERT … SELECT
UNIQUE direkt hinter einer Spalte
UNIQUE (spalte) als eigene Zeile
CHECK (…)
–
In einem ausgewachsenen Datenbanksystem stehen all diese Möglichkeiten zur Verfügung. Merkt euch die Einschränkungen also als Eigenart dieses Werkzeugs, nicht als Eigenschaft von SQL.