EMZETT.
Login

Kurz: * liefert alle Spalten (praktisch zum Erkunden, im Produktivcode besser Spalten benennen). AS vergibt Aliase. NULL bedeutet “unbekannt”: Rechnen mit NULL ergibt NULL.

Teil des Kurses SQL

Kapitel 4 von 15 im Kurs SQL (Abschnitt „Abfragen“). Mit Fortschritt, Quiz und Zertifikat auf der Lernseite.

SELECT

CREATE TABLE kunden (id INTEGER PRIMARY KEY, name TEXT NOT NULL, ort TEXT, punkte INTEGER);
CREATE TABLE bestellungen (id INTEGER PRIMARY KEY, kunde_id INTEGER, produkt TEXT, preis REAL, menge INTEGER, datum TEXT);
INSERT INTO kunden VALUES (1,'Mia','Berlin',120),(2,'Tom','Hamburg',80),(3,'Zoe','Berlin',200),(4,'Ben','München',NULL),(5,'Eva','Köln',150);
INSERT INTO bestellungen VALUES
 (1,1,'Laptop',999.00,1,'2025-01-10'),(2,1,'Maus',25.50,2,'2025-01-12'),(3,2,'Monitor',189.90,1,'2025-02-01'),
 (4,3,'Tastatur',49.00,1,'2025-02-15'),(5,3,'Maus',25.50,1,'2025-03-03'),(6,3,'Laptop',999.00,1,'2025-03-20'),
 (7,NULL,'Kabel',5.00,3,'2025-03-21');
SELECT * FROM kunden;
SELECT name, ort FROM kunden;
SELECT name AS kunde, punkte * 2 AS doppelt FROM kunden;

Ausgabe:

id  name  ort      punkte
--  ----  -------  ------
1   Mia   Berlin   120
2   Tom   Hamburg  80
3   Zoe   Berlin   200
4   Ben   München
5   Eva   Köln     150
name  ort
----  -------
Mia   Berlin
Tom   Hamburg
Zoe   Berlin
Ben   München
Eva   Köln
kunde  doppelt
-----  -------
Mia    240
Tom    160
Zoe    400
Ben
Eva    300

* liefert alle Spalten (praktisch zum Erkunden, im Produktivcode besser Spalten benennen). AS vergibt Aliase. NULL bedeutet “unbekannt”: Rechnen mit NULL ergibt NULL.

WHERE: filtern

CREATE TABLE kunden (id INTEGER PRIMARY KEY, name TEXT NOT NULL, ort TEXT, punkte INTEGER);
CREATE TABLE bestellungen (id INTEGER PRIMARY KEY, kunde_id INTEGER, produkt TEXT, preis REAL, menge INTEGER, datum TEXT);
INSERT INTO kunden VALUES (1,'Mia','Berlin',120),(2,'Tom','Hamburg',80),(3,'Zoe','Berlin',200),(4,'Ben','München',NULL),(5,'Eva','Köln',150);
INSERT INTO bestellungen VALUES
 (1,1,'Laptop',999.00,1,'2025-01-10'),(2,1,'Maus',25.50,2,'2025-01-12'),(3,2,'Monitor',189.90,1,'2025-02-01'),
 (4,3,'Tastatur',49.00,1,'2025-02-15'),(5,3,'Maus',25.50,1,'2025-03-03'),(6,3,'Laptop',999.00,1,'2025-03-20'),
 (7,NULL,'Kabel',5.00,3,'2025-03-21');
SELECT name, punkte FROM kunden WHERE punkte > 100;
SELECT name FROM kunden WHERE ort = 'Berlin' AND punkte >= 150;
SELECT name FROM kunden WHERE ort = 'Hamburg' OR ort = 'Köln';
SELECT name FROM kunden WHERE NOT ort = 'Berlin';
SELECT name FROM kunden WHERE punkte BETWEEN 100 AND 150;
SELECT name FROM kunden WHERE ort IN ('Berlin', 'Köln');

Ausgabe:

name  punkte
----  ------
Mia   120
Zoe   200
Eva   150
name
----
Zoe
name
----
Tom
Eva
name
----
Tom
Ben
Eva
name
----
Mia
Eva
name
----
Mia
Zoe
Eva
OperatorBedeutung
=, <> (oder !=)gleich, ungleich
<, <=, >, >=Vergleiche
AND, OR, NOTLogik (AND bindet stärker als OR; im Zweifel klammern)
BETWEEN a AND bvon a bis b, inklusive
IN (...)Wert in Liste
LIKETextmuster
IS NULL, IS NOT NULLTest auf fehlenden Wert

LIKE: Textmuster

% steht für beliebig viele Zeichen, _ für genau eines.

CREATE TABLE kunden (id INTEGER PRIMARY KEY, name TEXT NOT NULL, ort TEXT, punkte INTEGER);
CREATE TABLE bestellungen (id INTEGER PRIMARY KEY, kunde_id INTEGER, produkt TEXT, preis REAL, menge INTEGER, datum TEXT);
INSERT INTO kunden VALUES (1,'Mia','Berlin',120),(2,'Tom','Hamburg',80),(3,'Zoe','Berlin',200),(4,'Ben','München',NULL),(5,'Eva','Köln',150);
INSERT INTO bestellungen VALUES
 (1,1,'Laptop',999.00,1,'2025-01-10'),(2,1,'Maus',25.50,2,'2025-01-12'),(3,2,'Monitor',189.90,1,'2025-02-01'),
 (4,3,'Tastatur',49.00,1,'2025-02-15'),(5,3,'Maus',25.50,1,'2025-03-03'),(6,3,'Laptop',999.00,1,'2025-03-20'),
 (7,NULL,'Kabel',5.00,3,'2025-03-21');
SELECT name FROM kunden WHERE name LIKE 'M%';
SELECT name FROM kunden WHERE name LIKE '%e%';
SELECT name FROM kunden WHERE name LIKE '_en';
SELECT produkt FROM bestellungen WHERE produkt NOT LIKE '%a%' GROUP BY produkt;

Ausgabe:

name
----
Mia
name
----
Zoe
Ben
Eva
name
----
Ben
produkt
-------
Monitor

SQLite vergleicht LIKE bei ASCII ohne Rücksicht auf Groß-/Kleinschreibung; PostgreSQL nutzt dafür ILIKE.

NULL richtig prüfen

NULL = NULL ist nicht wahr, sondern wieder NULL. Nutze IS NULL:

CREATE TABLE kunden (id INTEGER PRIMARY KEY, name TEXT NOT NULL, ort TEXT, punkte INTEGER);
CREATE TABLE bestellungen (id INTEGER PRIMARY KEY, kunde_id INTEGER, produkt TEXT, preis REAL, menge INTEGER, datum TEXT);
INSERT INTO kunden VALUES (1,'Mia','Berlin',120),(2,'Tom','Hamburg',80),(3,'Zoe','Berlin',200),(4,'Ben','München',NULL),(5,'Eva','Köln',150);
INSERT INTO bestellungen VALUES
 (1,1,'Laptop',999.00,1,'2025-01-10'),(2,1,'Maus',25.50,2,'2025-01-12'),(3,2,'Monitor',189.90,1,'2025-02-01'),
 (4,3,'Tastatur',49.00,1,'2025-02-15'),(5,3,'Maus',25.50,1,'2025-03-03'),(6,3,'Laptop',999.00,1,'2025-03-20'),
 (7,NULL,'Kabel',5.00,3,'2025-03-21');
SELECT name FROM kunden WHERE punkte = NULL;
SELECT name FROM kunden WHERE punkte IS NULL;
SELECT name, punkte FROM kunden WHERE punkte IS NOT NULL AND punkte < 130;
SELECT NULL = NULL AS a, NULL IS NULL AS b, 1 + NULL AS c;

Ausgabe:

name
----
Ben
name  punkte
----  ------
Mia   120
Tom   80
a  b  c
-  -  -
   1

Sortieren, begrenzen, Duplikate

CREATE TABLE kunden (id INTEGER PRIMARY KEY, name TEXT NOT NULL, ort TEXT, punkte INTEGER);
CREATE TABLE bestellungen (id INTEGER PRIMARY KEY, kunde_id INTEGER, produkt TEXT, preis REAL, menge INTEGER, datum TEXT);
INSERT INTO kunden VALUES (1,'Mia','Berlin',120),(2,'Tom','Hamburg',80),(3,'Zoe','Berlin',200),(4,'Ben','München',NULL),(5,'Eva','Köln',150);
INSERT INTO bestellungen VALUES
 (1,1,'Laptop',999.00,1,'2025-01-10'),(2,1,'Maus',25.50,2,'2025-01-12'),(3,2,'Monitor',189.90,1,'2025-02-01'),
 (4,3,'Tastatur',49.00,1,'2025-02-15'),(5,3,'Maus',25.50,1,'2025-03-03'),(6,3,'Laptop',999.00,1,'2025-03-20'),
 (7,NULL,'Kabel',5.00,3,'2025-03-21');
SELECT name, punkte FROM kunden ORDER BY punkte DESC;
SELECT name, ort FROM kunden ORDER BY ort ASC, name DESC;
SELECT name FROM kunden ORDER BY punkte DESC LIMIT 2;
SELECT name FROM kunden ORDER BY punkte DESC LIMIT 2 OFFSET 2;
SELECT DISTINCT ort FROM kunden ORDER BY ort;
SELECT DISTINCT produkt, preis FROM bestellungen ORDER BY preis;

Ausgabe:

name  punkte
----  ------
Zoe   200
Eva   150
Mia   120
Tom   80
Ben
name  ort
----  -------
Zoe   Berlin
Mia   Berlin
Tom   Hamburg
Eva   Köln
Ben   München
name
----
Zoe
Eva
name
----
Mia
Tom
ort
-------
Berlin
Hamburg
Köln
München
produkt   preis
--------  -----
Kabel     5.0
Maus      25.5
Tastatur  49.0
Monitor   189.9
Laptop    999.0
  • ORDER BY sortiert (ASC aufsteigend ist Standard, DESC absteigend)
  • LIMIT n OFFSET m begrenzt und überspringt (Seitenweise Anzeige). SQL Server nutzt TOP n bzw. OFFSET ... FETCH.
  • DISTINCT entfernt doppelte Zeilen
  • Ohne ORDER BY ist die Reihenfolge nicht garantiert

Reihenfolge der Verarbeitung

SQL schreibt man in einer anderen Reihenfolge, als es ausgeführt wird:

SchrittKlausel
1FROM / JOIN (Tabellen)
2WHERE (Zeilen filtern)
3GROUP BY (gruppieren)
4HAVING (Gruppen filtern)
5SELECT (Spalten berechnen)
6DISTINCT
7ORDER BY
8LIMIT

Deshalb darf ein Alias aus SELECT in WHERE meist nicht benutzt werden, in ORDER BY schon.

Merke

  • SELECT spalten FROM tabelle WHERE bedingung ORDER BY ... LIMIT ...
  • Filtern mit =, <>, BETWEEN, IN, LIKE, AND/OR/NOT
  • Fehlende Werte nur mit IS NULL / IS NOT NULL prüfen
  • Ohne ORDER BY keine feste Reihenfolge
  • Klammere gemischte AND/OR-Bedingungen

Übungsaufgabe

Zeige die drei teuersten Bestellpositionen (Produkt, Preis), ohne Duplikate bei Produkt und Preis.

Quiz zur Selbstkontrolle

Weiter im Kurs

Zurück: Daten einfügen, ändern und löschen

Weiter: Funktionen für Text, Zahlen, Datum und NULL

Alle Kapitel: SQL im Überblick