SemaTrain Logo Ein Fachportal von SemaTrain

SELECT, WHERE, ORDER BY

Sie lernen die wichtigsten SQL-Bausteine für den Alltag: SELECT (Abfrage), WHERE (Filter) und ORDER BY (Sortierung) – mit Beispielen rund um Kurse, Termine und Trainer.

Hinweis: SQL-Syntax ist in vielen Systemen ähnlich. Details (z. B. Datum-Funktionen) variieren leicht zwischen SQLite/PostgreSQL/MySQL.

SQL Grundlagen Schulung – Kursbezug

Dieses Kapitel ist Teil des Lernpfads zur SQL Grundlagen Schulung. Termine & Buchung laufen über SemaTrain.de.

Hinweis: Beispiele nutzen ein kleines Schulungs-Schema (Kurse/Trainer/Termine).

Worum geht’s?

Lehr-/Lernziele

Mini-Datenbasis (für Beispiele)

Sie können diese Inserts in SQLite/PostgreSQL/MySQL sinngemäß nutzen (IDs/Datumsfunktionen ggf. anpassen).
Schema-Hinweis: konsistent zu Kapitel 01: kurse(kurs_id,kurs_name) und termine(termin_id,kurs_id,trainer_id,start_datum,ort,format,dauer_tage,preis_eur).

Beispieldaten (Kurse/Trainer/Termine) (SQL)
-- Tabellen (Schema-Beispiel)
-- kurse(kurs_id, kurs_name)
-- trainer(trainer_id, name)
-- termine(termin_id, kurs_id, trainer_id, start_datum, ort, format, dauer_tage, preis_eur)

INSERT INTO kurse (kurs_id, kurs_name) VALUES
  (1, 'SQL Grundlagen Schulung'),
  (2, 'Java Grundlagen Schulung'),
  (3, 'Python Schulung');

INSERT INTO trainer (trainer_id, name) VALUES
  (1, 'Mathias Ellmann'),
  (2, 'Gasttrainer');

-- trainer_id ist einmal NULL, damit wir später IS NULL und LEFT JOIN zeigen können
INSERT INTO termine (termin_id, kurs_id, trainer_id, start_datum, ort, format, dauer_tage, preis_eur) VALUES
  (1, 1, 1,    '2026-02-23', 'Hamburg', 'Praesenz', 3, 1428.00),
  (2, 1, NULL, '2026-03-09', 'Hamburg', 'Online',   3, 1428.00),
  (3, 2, 2,    '2026-03-10', 'Berlin',  'Praesenz', 2,  999.00),
  (4, 3, 2,    '2026-04-06', 'remote',  'Online',   3, 1428.00);

SELECT: Spalten wählen, Aliases, DISTINCT

1) Nur benötigte Spalten

SELECT – Spaltenauswahl (SQL)
SELECT kurs_id, kurs_name
FROM kurse;

Tipp: SELECT * vermeiden – besonders bei großen Tabellen.

2) Aliases (lesbare Ausgabe)

Aliases mit AS (SQL)
SELECT
  kurs_name AS kurs
FROM kurse
ORDER BY kurs_name ASC;
DISTINCT (Duplikate entfernen)
DISTINCT – eindeutige Orte (SQL)
SELECT DISTINCT ort
FROM termine
ORDER BY ort ASC;

WHERE: filtern (Vergleich, IN, BETWEEN, LIKE, NULL)

1) Vergleich + AND/OR

WHERE mit AND (SQL)
SELECT termin_id, start_datum, ort, format
FROM termine
WHERE ort = 'Hamburg'
  AND format = 'Online';

2) IN & BETWEEN

IN + BETWEEN (SQL)
SELECT termin_id, start_datum, ort
FROM termine
WHERE ort IN ('Hamburg', 'Berlin')
  AND start_datum BETWEEN '2026-03-01' AND '2026-03-31';
LIKE (Pattern-Suche)
LIKE – Kursname enthält 'SQL' (SQL)
SELECT kurs_id, kurs_name
FROM kurse
WHERE kurs_name LIKE '%SQL%'
ORDER BY kurs_name ASC;

Hinweis: Case-Sensitivity hängt vom System/Kollation ab.

NULL richtig filtern
NULL: IS NULL / IS NOT NULL (Beispiel trainer_id) (SQL)
-- FALSCH: WHERE trainer_id = NULL
-- RICHTIG:
SELECT termin_id, kurs_id, trainer_id, start_datum, ort, format
FROM termine
WHERE trainer_id IS NULL
ORDER BY start_datum ASC;

SELECT termin_id, kurs_id, trainer_id, start_datum, ort, format
FROM termine
WHERE trainer_id IS NOT NULL
ORDER BY start_datum ASC;

Praxisbezug: trainer_id ist im Lernpfad absichtlich manchmal NULL, damit LEFT JOIN in Kapitel 03 Sinn ergibt.

ORDER BY: sortieren (ASC/DESC, mehrere Kriterien)

1) Einfach sortieren

ORDER BY start_datum ASC (SQL)
SELECT termin_id, start_datum, ort
FROM termine
ORDER BY start_datum ASC;

2) Mehrfachsortierung

ORDER BY ort, start_datum DESC (SQL)
SELECT termin_id, start_datum, ort, format
FROM termine
ORDER BY ort ASC, start_datum DESC;

Typische Stolperfallen

Praxisaufgabe

  1. Geben Sie alle Termine aus, die im März 2026 starten (BETWEEN).
  2. Filtern Sie nur Online-Termine in Hamburg.
  3. Sortieren Sie die Ausgabe nach Ort (ASC) und Startdatum (ASC).
  4. Geben Sie Spalten mit Alias aus: start_datum AS start, kurs_id AS kurs.
Lösungsvorschlag anzeigen
Lösung: WHERE + ORDER BY + Alias (SQL)
SELECT
  termin_id,
  kurs_id AS kurs,
  start_datum AS start,
  ort,
  format
FROM termine
WHERE start_datum BETWEEN '2026-03-01' AND '2026-03-31'
  AND ort = 'Hamburg'
  AND format = 'Online'
ORDER BY ort ASC, start_datum ASC;

Kurz-Takeaways

Quiz: SELECT, WHERE, ORDER BY

1. (LZ1) Was ist der Hauptzweck von SELECT?

2. (LZ2) Wie filtert man korrekt auf NULL?

3. (LZ2) Welche Bedingung trifft „Ort ist Hamburg oder Berlin“ am besten?

4. (LZ3) Wie sortiert man nach start_datum absteigend?

Praxisaufgabe

Mini-Projekt: „Termin-Finder“ – Filter, Sortierung, Logik (ohne JOIN)

Sie bauen eine kleine Sammlung an Abfragen, wie sie in echten Tools/Reports vorkommt. Fokus: SELECT/WHERE/ORDER BY – bewusst ohne JOIN (kommt in Kapitel 03).

Beitrag zu den Lehr-/Lernzielen: LZ1 (Spalten/Alias), LZ2 (Filter), LZ3 (Sortierung), LZ4 (NULL/AND-OR/Klammern).

Stufe A – Warm-up (SELECT sauber)

Stufe B – Filter-Power (WHERE)

Stufe C – Logik & Stolperfallen (AND/OR)

Stufe D – Mini-Report (ohne JOIN)

Stufe E – Parameter-Denken (App-ready)

Musterlösung anzeigen
Projektlösung: Termin-Finder (ohne JOINs) (SQL)
-- ==========================================================
-- Stufe A – Warm-up (SELECT sauber)
-- ==========================================================

-- (A1) Kurse: nur relevante Spalten + Alias
SELECT
  kurs_id,
  kurs_name AS kurs
FROM kurse
ORDER BY kurs_name ASC;

-- (A2) DISTINCT: Welche Orte gibt es überhaupt?
SELECT DISTINCT ort
FROM termine
ORDER BY ort ASC;

-- ==========================================================
-- Stufe B – Filter-Power (WHERE)
-- ==========================================================

-- (B1) Online-Termine in Hamburg oder remote
SELECT termin_id, kurs_id, trainer_id, start_datum, ort, format
FROM termine
WHERE format = 'Online'
  AND ort IN ('Hamburg','remote')
ORDER BY start_datum ASC;

-- (B2) Termine im März 2026 (Zeitraum)
SELECT termin_id, kurs_id, start_datum, ort, format
FROM termine
WHERE start_datum BETWEEN '2026-03-01' AND '2026-03-31'
ORDER BY start_datum ASC;

-- (B3) LIKE: Kurse, die "SQL" im Namen haben
SELECT kurs_id, kurs_name
FROM kurse
WHERE kurs_name LIKE '%SQL%'
ORDER BY kurs_name ASC;

-- (B4) NULL korrekt: Termine ohne Trainer (passt zur LEFT JOIN-Story in Kap. 03)
SELECT termin_id, kurs_id, trainer_id, start_datum, ort, format
FROM termine
WHERE trainer_id IS NULL
ORDER BY start_datum ASC;

-- ==========================================================
-- Stufe C – Logik & Stolperfallen (AND/OR + Klammern)
-- ==========================================================

-- (C1) RICHTIG: (A OR B) AND C
SELECT termin_id, start_datum, ort, format
FROM termine
WHERE (ort = 'Hamburg' OR ort = 'Berlin')
  AND format = 'Praesenz'
ORDER BY start_datum ASC;

-- (C2) FALSCH (nur zur Erinnerung): ohne Klammern bindet AND stärker als OR
-- Ergebnis ist dann: ort='Hamburg' OR (ort='Berlin' AND format='Praesenz')
-- SELECT ... WHERE ort='Hamburg' OR ort='Berlin' AND format='Praesenz';

-- ==========================================================
-- Stufe D – Mini-Report (ohne JOIN)
-- ==========================================================

-- (D1) "Nächste Termine": einfach nach Datum sortieren
SELECT termin_id, kurs_id, start_datum, ort, format
FROM termine
ORDER BY start_datum ASC;

-- (D2) Optional (sehr gängig): nur die nächsten 3
-- DB-Hinweis: LIMIT funktioniert in SQLite/MySQL/PostgreSQL.
SELECT termin_id, kurs_id, start_datum, ort, format
FROM termine
ORDER BY start_datum ASC
LIMIT 3;

-- ==========================================================
-- Stufe E – Parameter-Denken (Prepared Statements)
-- ==========================================================

-- (E1) App-ready: Werte als Parameter denken (Syntax je nach Tool/Driver)
-- Beispiel-Parameter: :format, :ort1, :ort2, :fromDate, :toDate
SELECT termin_id, kurs_id, start_datum, ort, format
FROM termine
WHERE format = :format
  AND ort IN (:ort1, :ort2)
  AND start_datum BETWEEN :fromDate AND :toDate
ORDER BY start_datum ASC, ort ASC;

Ausblick: In Kapitel 03 (JOINs) verbinden wir termine mit kurse (und trainer) und machen daraus echte Reports mit Kursnamen/Trainer – die Filter-Logik aus diesem Kapitel bleibt dabei 1:1 nutzbar.