Premium
SQL in der Praxis
5 Min. Lesezeit·

SQL-String-Funktionen mit Beispielen

Alle String-Aufgaben in SQL laufen auf vier Aktionen hinaus: verbinden, ausschneiden, bereinigen und suchen. Der Spickzettel der wichtigsten Funktionen:

AufgabeFunktionen
Strings verbindenCONCAT, CONCAT_WS, GROUP_CONCAT / STRING_AGG
Einen Teil ausschneidenSUBSTRING, LEFT, RIGHT
BereinigenTRIM, REPLACE
Groß-/KleinschreibungUPPER, LOWER
Suchen und messenPOSITION, LIKE, LENGTH / CHAR_LENGTH

Gehen wir jede Gruppe an Beispielen aus der Datenbank eines Lieferdienstes durch — jede Abfrage lässt sich direkt im Artikel ausführen.

Verbinden: CONCAT und CONCAT_WS

CONCAT fügt beliebig viele Strings zu einem zusammen:

MySQL 8.1
SELECT CONCAT(name, ' — ', category) AS title
FROM products
ORDER BY product_id
LIMIT 3;
title
Margherita Pizza — Food
Caesar Salad — Food
Cheeseburger — Food

Wiederholt sich der Trenner, ist CONCAT_WS („with separator") bequemer: Das erste Argument ist der Trenner, danach folgen die Teile:

MySQL 8.1
SELECT CONCAT_WS(', ', country, acquisition_channel) FROM users;
-- 'Germany, Ads'

PostgreSQL und Standard-SQL bieten zusätzlich den Operator ||: name || ' — ' || category. In MySQL bedeutet || standardmäßig logisches ODER — für portablen Code ist CONCAT die sichere Wahl.

Die NULL-Falle bei der Verkettung

Bei NULL verhalten sich die Verkettungsfunktionen unterschiedlich — eine beliebte Quelle leerer Strings in Berichten:

  • MySQL: CONCAT('a', NULL, 'b') liefert NULL — ein einziger leerer Wert „vergiftet" das ganze Ergebnis.
  • PostgreSQL: CONCAT('a', NULL, 'b') liefert abNULL wird einfach übersprungen. Der Operator || verhält sich allerdings wie MySQL: 'a' || NULL ergibt NULL.

Können die zu verbindenden Spalten Lücken enthalten, wickeln Sie sie in COALESCE ein — oder nehmen Sie CONCAT_WS, das NULL in beiden DBMS ignoriert.

Was liefert CONCAT('Bestellung Nr. ', order_id, ' mit ', promo_code) in MySQL, wenn promo_code NULL ist?

Eine Gruppe von Zeilen verbinden: GROUP_CONCAT und STRING_AGG

Eine eigene Superkraft: Werte aus mehreren Tabellenzeilen zu einem String einsammeln. Bauen wir die Produktliste jeder Kategorie:

In MySQL erledigt das GROUP_CONCAT:

MySQL 8.1
SELECT category, GROUP_CONCAT(name ORDER BY name SEPARATOR ', ') AS product_list
FROM products
GROUP BY category
ORDER BY category;

In PostgreSQL löst dieselbe Aufgabe STRING_AGG:

PostgreSQL 17.5
SELECT category, STRING_AGG(name, ', ' ORDER BY name) AS product_list
FROM products
GROUP BY category
ORDER BY category;
categoryproduct_list
DrinksCoca-Cola 0.5L, Fresh Orange Juice, Green Smoothie, Latte, Mineral Water 1L
FoodCaesar Salad, Cheeseburger, Margherita Pizza, Pad Thai, Sushi Set
GroceryOlive Oil 500ml, Rice 1kg
SnacksChips Pack, Dark Chocolate, Granola Bar

Die Funktionen heißen unterschiedlich — GROUP_CONCAT in MySQL, STRING_AGG in PostgreSQL —, tun aber dasselbe. Es sind Aggregatfunktionen wie SUM oder COUNT, sie arbeiten also mit GROUP BY zusammen.

Welche Funktion sammelt in PostgreSQL Werte aus mehreren Tabellenzeilen zu einer kommagetrennten Liste?

Ausschneiden: SUBSTRING, LEFT, RIGHT

SUBSTRING(string, position, länge) schneidet ein Fragment aus einem String; die Zeichen werden ab eins gezählt. Im Duo mit POSITION, das die Position eines Teilstrings findet, ergeben sich praktische Tricks — etwa die Domain aus einer E-Mail herauslösen:

MySQL 8.1
SELECT email, SUBSTRING(email, POSITION('@' IN email) + 1) AS domain
FROM users
ORDER BY user_id
LIMIT 3;
emaildomain
jessicalopez@gmail.comgmail.com
joseph.garcia@yahoo.comyahoo.com
margaret.anderson3@hotmail.comhotmail.com

POSITION('@' IN email) liefert die Position des Zeichens @, und SUBSTRING ohne drittes Argument nimmt alles von dieser Position bis zum Ende des Strings. Probieren Sie es selbst: Holen Sie den Login aus der E-Mail — den Teil vor dem @. Sie brauchen das dritte Argument und POSITION('@' IN email) - 1.

Für die Ränder eines Strings gibt es Abkürzungen: LEFT(string, n) — die ersten n Zeichen, RIGHT(string, n) — die letzten n.

Bereinigen: TRIM und REPLACE

TRIM entfernt Leerzeichen an beiden Enden eines Strings — erste Hilfe bei von Menschen eingegebenen Daten:

MySQL 8.1
SELECT TRIM('  SUMMER20  ');
-- 'SUMMER20'

REPLACE(string, suchen, ersetzen) ersetzt alle Vorkommen eines Teilstrings:

MySQL 8.1
SELECT phone, REPLACE(REPLACE(phone, '-', ''), ' ', '') AS normalized
FROM users
WHERE user_id IN (1, 4)
ORDER BY user_id;
phonenormalized
+1 196 378 5287+11963785287
1-508-436-743415084367434

Verschachtelte REPLACE-Aufrufe sind der übliche Trick, um Telefonnummern und Artikelnummern vor dem Vergleich zu normalisieren. Für Ersetzungen nach Muster statt nach exaktem Teilstring gibt es REGEXP_REPLACE — Muster behandeln wir ausführlich in der Lektion Der REGEXP-Operator.

Ein Sonderfall der Bereinigung sind leere Strings und Strings aus Leerzeichen anstelle von NULL. Das löst die Kombination COALESCE(NULLIF(TRIM(...), ''), ...), die wir im COALESCE-Artikel zerlegt haben.

Groß-/Kleinschreibung und Länge: UPPER, LOWER, LENGTH

UPPER und LOWER wandeln einen String in Groß- bzw. Kleinbuchstaben um. Der Klassiker ist der Vergleich ohne Beachtung der Schreibung: LOWER(email) = LOWER('User@Mail.com').

Bei der Stringlänge gibt es eine Nuance, die man vorher kennen sollte:

  • MySQL: LENGTH() zählt Bytes, CHAR_LENGTH() zählt Zeichen. Bei lateinischem Text fällt beides zusammen, aber ein kyrillischer Buchstabe belegt in UTF-8 zwei Bytes: LENGTH('привет') liefert 12, CHAR_LENGTH('привет') liefert 6.
  • PostgreSQL: LENGTH() zählt von vornherein Zeichen — LENGTH('привет') liefert 6.

Wenn Sie die Länge brauchen, wie ein Mensch sie sieht — nehmen Sie CHAR_LENGTH: Sie funktioniert in beiden DBMS gleich.

MySQL vs. PostgreSQL: die Vergleichstabelle

AufgabeMySQLPostgreSQL
String-VerkettungCONCAT, CONCAT_WSCONCAT, CONCAT_WS, ||
CONCAT mit NULLLiefert NULLÜberspringt NULL
String-AggregationGROUP_CONCATSTRING_AGG
Länge in ZeichenCHAR_LENGTHLENGTH oder CHAR_LENGTH
Teilstring-PositionPOSITION, LOCATEPOSITION, STRPOS
Ersetzung nach MusterREGEXP_REPLACEREGEXP_REPLACE

Wie weiter

Passende Artikel