Berechnete Spalten in SQL: Funktionen und CASE
AnfängerEinheit 3 von 6 in Kurs: SQL – Datenbanken abfragen mit SELECT, JOIN und GROUP BY
Was du lernst
- Berechne für jede Zeile neue Werte mit arithmetischen Ausdrücken und Funktionen, gib den Ergebnissen klare Namen und verhindere, dass Datentypen das Ergebnis verändern.
- Neue Spalten berechnen und mit Aliasen benennenSchreibe Ausdrücke in die SELECT-Liste, benenne die Ergebnisse mit AS und lerne, wo in einer Abfrage diese Namen verwendet werden können.
- Mit arithmetischen Operatoren und Zahlenfunktionen rechnenVerwende +, -, *, / und % in der richtigen Reihenfolge, vermeide Überraschungen bei der ganzzahligen Division und runde Ergebnisse mit ROUND und verwandten Funktionen.
- Werte zwischen Datentypen umwandelnErkenne den Typ jedes Werts, wandle ihn mit CAST explizit um und erkenne automatische Umwandlungen, die Sortierung, Vergleiche und Ergebnisse verändern.
- Neue Spalten berechnen und mit Aliasen benennen
- Sage vorher, wie sich NULL auf Berechnungen, Vergleiche und Filter auswirkt, und ersetze oder erzeuge fehlende Werte gezielt.
- Vorhersagen, wie sich NULL in Berechnungen und Bedingungen verhältErkläre, was NULL bedeutet, wie es sich in Ausdrücken ausbreitet und warum eine Bedingung mit NULL weder wahr noch falsch ist.
- Fehlende Werte mit COALESCE ersetzen und mit NULLIF erzeugenFülle Lücken mit COALESCE, wandle Nullen und Platzhalterwerte mit NULLIF in NULL um und wähle Ersatzwerte, die die Bedeutung der Daten erhalten.
- Vorhersagen, wie sich NULL in Berechnungen und Bedingungen verhält
- Verkette, bereinige, miss und zerlege Textwerte, damit Namen, E-Mail-Adressen und Codes einheitlich und nutzbar sind.
- Textwerte verketten und bereinigenVerkette Texte, ändere die Groß- und Kleinschreibung, entferne Leerzeichen und ersetze Zeichen. Verschachtle diese Funktionen, um uneinheitliche Eingaben zu bereinigen.
- Textlängen bestimmen und Textteile extrahierenZähle Zeichen, finde die Position eines Zeichens und schneide Textteile anhand von Positionen aus, die bei 1 beginnen.
- Textwerte verketten und bereinigen
- Schreibe und lies Datumswerte richtig, zerlege und formatiere sie und rechne mit Tagen, Monaten und Zeitspannen.
- Datums- und Zeitwerte schreiben, speichern und lesenLerne die Datums- und Zeittypen kennen, schreibe Datumswerte im eindeutigen ISO-Format, wandle Text in Datumswerte um und ermittle das aktuelle Datum und die aktuelle Uhrzeit.
- Bestandteile von Datumswerten extrahieren und formatierenExtrahiere Jahr, Monat oder Wochentag, gruppiere Datumswerte nach Zeitraum und wandle sie in lesbaren Text um.
- Mit Datumswerten rechnen und nach Datumsbereichen filternAddiere Tage und Monate, bestimme die Zeit zwischen zwei Datumswerten und schreibe Datumsfilter, die alle Zeilen eines Zeitraums erfassen.
- Datums- und Zeitwerte schreiben, speichern und lesen
- Wandle Bedingungen mit CASE in Bezeichnungen, Kategorien und benutzerdefinierte Sortierreihenfolgen um und kombiniere CASE mit den anderen Funktionen in vollständigen Berichtsabfragen.
- Zeilen mit CASE-Suchausdrücken in Kategorien einteilenSchreibe CASE WHEN … THEN … ELSE … END, ordne die Bedingungen so an, dass jede Zeile in der richtigen Gruppe landet, und behandle Grenzwerte und NULL-Werte.
- Einfache CASE-Ausdrücke nutzen und CASE an verschiedenen Stellen einer Abfrage einsetzenÜbersetze Codes mit einfachen CASE-Ausdrücken, erstelle Flags und benutzerdefinierte Sortierreihenfolgen und erkenne die kürzeren Formen, die andere Datenbanken anbieten.
- Funktionen zu einer vollständigen Berichtsabfrage kombinierenErstelle schrittweise einen Bericht mit mehreren berechneten Spalten, verschachtle Funktionen richtig und prüfe jede Spalte anhand von Zeilen, die du von Hand berechnet hast.
- Zeilen mit CASE-Suchausdrücken in Kategorien einteilen
Berechnete Spalten in SQL einfach erklärt
1Berechnete Spalten mit Ausdrücken und Aliasen erstellen
Berechnete Spalten machen aus den bereits in einer Zeile vorhandenen Werten nützliche Ergebnisse: einen Positionsbetrag, einen Rabatt oder eine prozentuale Änderung. Klare Aliase machen diese Ergebnisse lesbar, während Klammern und Datentypen bestimmen, was SQL tatsächlich berechnet. Du erstellst Ausdrücke in kleinen Schritten, siehst, warum ganzzahlige Division einen Nachkommateil beseitigen kann, und wählst explizite Typumwandlungen, wenn die gespeicherte Form nicht zur Operation passt.
1.1 Neue Spalten berechnen und mit Aliasen benennen
Eine Ergebnisspalte kann einen Wert anzeigen, der nirgendwo in der Tabelle gespeichert ist. SQL berechnet ihn aus der aktuellen Zeile. Ein Ausdruck kombiniert Spalten, feste Werte, Operatoren und Funktionsaufrufe.
Einen Wert für jede Zeile berechnen
SELECT order_id,
quantity * unit_price AS line_total
FROM orders;
Bei Menge 3 und Stückpreis 12,50 zeigt die neue Spalte 37.5. Jede Zeile liefert ihre eigene Menge und ihren eigenen Preis. Die Abfrage lässt die gespeicherten Spalten unverändert. Eine Einzelzeilenfunktion wie ROUND(unit_price, 0) gibt ebenfalls einen Wert pro Eingabezeile zurück. Nimmst du sie in die SELECT-Liste auf, werden keine Zeilen zusammengefasst. Eine Aggregatfunktion wie SUM oder AVG berechnet dagegen einen Wert für eine Gruppe.
Der Name nach AS ist ein Spaltenalias: eine Überschrift für das Ergebnis. Ohne ihn verwendet SQLite den Ausdruckstext als Überschrift; PostgreSQL verwendet für diesen arithmetischen Ausdruck ?column?. AS ist optional, macht es aber leichter, einen Namen von einem fehlenden Komma zu unterscheiden.
Namen und Anführungszeichen wählen
Verwende einen einfachen Namen wie line_total: Buchstaben, Ziffern und Unterstriche, beginnend mit einem Buchstaben. Ein Name mit Leerzeichen oder ein reserviertes Wort braucht doppelte Anführungszeichen: AS "Line Total" oder AS "order". Einfache Anführungszeichen kennzeichnen Textwerte wie 'Boston'. MySQL akzeptiert für Namen auch Graviszeichen und SQL Server eckige Klammern.
PostgreSQL wandelt Namen ohne Anführungszeichen in Kleinbuchstaben um: AS LineTotal erzeugt linetotal. Doppelte Anführungszeichen erhalten die Schreibweise in AS "LineTotal". SQLite behält einen Alias wie eingegeben bei. Namen in Kleinbuchstaben mit Unterstrichen funktionieren in beiden Systemen gut.
Einen Alias im richtigen Verarbeitungsschritt verwenden
Die logische Reihenfolge lautet FROM, WHERE, SELECT und dann ORDER BY. Die Tabelle wird gewählt und Zeilen werden gefiltert, bevor Ausgabeausdrücke ihre Aliase erhalten. Danach wird sortiert.
SELECT order_id,
quantity * unit_price AS line_total
FROM orders
WHERE quantity * unit_price > 100
ORDER BY line_total DESC;
ORDER BY kann line_total verwenden. Standard-SQL, PostgreSQL und MySQL können diesen neuen Alias nicht in WHERE verwenden; wiederhole dort den Ausdruck. SQLite akzeptiert einen Alias in WHERE als Erweiterung, aber diese Form scheitert, wenn sie nach PostgreSQL übertragen wird.
Ein neuer Alias steht auch einem anderen Ausdruck in derselben SELECT-Liste nicht zur Verfügung. Nach unit_price * 1.08 AS with_tax scheitert with_tax - unit_price AS tax, wenn die Tabelle keine Spalte with_tax hat. Schreibe stattdessen unit_price * 1.08 - unit_price AS tax.
Ein überraschendes Ergebnis untersuchen
SELECT first_name last_name FROM customers; ist gültiges SQL. Es zeigt eine Spalte mit Vornamen und dem Alias last_name an. Um beide Spalten abzurufen, schreibe SELECT first_name, last_name FROM customers;. Ein fehlendes Komma kann also ohne Fehlermeldung ein irreführendes Ergebnis liefern.
Für eine schnelle Prüfung eines Ausdrucks ist keine Tabelle nötig: SELECT 19.99 * 3 AS total; gibt in SQLite und PostgreSQL 59.97 zurück. Oracle vor Release 23 verlangt für diese Abfrage FROM DUAL; Release 23 und spätere Versionen erlauben auch SELECT ohne FROM.
Wichtige Erkenntnisse
- Eine berechnete Spalte berechnet für jede Zeile einen Wert, ohne gespeicherte Daten zu ändern.
- Eine Einzelzeilenfunktion erhält die Zeilen; eine Aggregatfunktion fasst Werte einer Gruppe zusammen.
- Verwende doppelte Anführungszeichen für Namen, die sie benötigen, und einfache für Textwerte.
- ORDER BY kann einen Ausgabealias verwenden; wiederhole den Ausdruck in einer übertragbaren WHERE-Klausel.
- Ein neuer Alias steht an anderer Stelle derselben SELECT-Liste nicht zur Verfügung.
- Ein fehlendes Komma kann den nächsten Spaltennamen in einen Alias verwandeln.
1.2 Mit arithmetischen Operatoren und Zahlenfunktionen rechnen
Arithmetische Ausdrücke machen aus Rohmengen Beträge, Raten und Differenzen. Die Operatoren sind +, -, *, / und %; Modulo liefert den Rest nach einer Division.
Die Reihenfolge der Berechnung steuern
Multiplikation, Division und Modulo kommen vor Addition und Subtraktion. Operatoren gleichen Ranges werden von links nach rechts ausgeführt. Daher ergibt 10 + 3 * 2 den Wert 16, während (10 + 3) * 2 den Wert 26 ergibt.
Für Menge 3, Stückpreis 12,50 und Rabattprozentsatz 10:
quantity * unit_price * (1 - discount_pct / 100.0)
Zuerst ergibt 10 / 100.0 den Wert 0.1. Die Klammern liefern den bezahlten Anteil 0.9. Der Bruttobetrag ist 37.5, der Nettobetrag also 33.75. Ohne Klammern zieht quantity * unit_price * 1 - discount_pct / 100.0 den Wert 0.1 von 37.5 ab und ergibt 37.4.
Nachkommateile bei der Division erhalten
In SQLite, PostgreSQL und SQL Server schneidet die Division einer Ganzzahl durch eine Ganzzahl den Nachkommateil in Richtung null ab: 7 / 2 ergibt 3 und -7 / 2 ergibt -3. MySQL und Oracle liefern bei / ein Dezimalergebnis. Mache in SQLite und PostgreSQL einen Operanden vor der Division zu einer Dezimalzahl: 7 / 2.0, 7 * 1.0 / 2 oder CAST(7 AS REAL) / 2 ergibt 3.5. Bei CAST(7 / 2 AS REAL) ist es zu spät und das Ergebnis ist 3.0.
Bei einem Anstieg von 80 auf 92 ergibt (92 - 80) * 100.0 / 80 den Wert 15.0 Prozent. Wird die ganzzahlige Differenz zuerst durch 80 dividiert, geht der Nachkommateil verloren. Modulo erhält den Rest: 135 / 60 ergibt 2 Stunden und 135 % 60 ergibt 15 Minuten. In SQLite und PostgreSQL ergibt -7 % 3 den Wert -1; der Rest erhält das Vorzeichen des linken Operanden. Oracle schreibt MOD(17, 5) statt %.
Ein Divisor von null löst in PostgreSQL und SQL Server einen Fehler aus; SQLite und MySQL geben NULL zurück. Mit amount / NULLIF(divisor, 0) ergibt der Fall null in allen diesen Systemen NULL.
Runden oder eine ganze Zahl wählen
ROUND(x, n) rundet auf n Dezimalstellen. Eine Lampe mit einem Preis von 24,00 und Kosten von 15,50 hat einen Gewinn von 8.5. ROUND((price - cost) / price * 100, 1) ergibt eine Marge von 35.4 Prozent. PostgreSQL unterstützt negative Stellenzahlen: ROUND(1234.5678, -2) ergibt 1200; SQLite behandelt die Stellenzahl als null und ergibt 1235.0.
| Funktion | Bedeutung | Beispiel |
|---|---|---|
ABS | Abstand von null | ABS(-4.2) ergibt 4.2 |
CEIL | Kleinste ganze Zahl, die mindestens so groß ist | CEIL(4.1) ergibt 5 |
FLOOR | Größte ganze Zahl, die höchstens so groß ist | FLOOR(-4.1) ergibt -5 |
TRUNC | Den Nachkommateil in Richtung null abschneiden | TRUNC(42.8) ergibt 42 |
PostgreSQL stellt diese Funktionen bereit. SQLite stellt ABS bereit; CEIL, FLOOR und TRUNC benötigen eine mit mathematischen Funktionen kompilierte Version, verfügbar ab 3.35.
Die Genauigkeit auf die Daten abstimmen
ROUND in SQLite und ROUND für numeric in PostgreSQL runden exakte Halbwerte von null weg: ROUND(-2.5) ergibt -3. PostgreSQL rundet Gleitkommahalbwerte gewöhnlich zur nächsten geraden ganzen Zahl; ROUND mit zwei Argumenten benötigt dort numeric, verwende also ROUND(CAST(x AS numeric), 2) für eine Spalte mit doppelter Gleitkommagenauigkeit.
Gleitkommazahlen bilden viele Dezimalbrüche nur näherungsweise ab. In SQLite kann 0.1 + 0.2 = 0.3 falsch sein und ROUND(2.675, 2) den Wert 2.67 zurückgeben. Dezimalliterale in PostgreSQL verwenden exaktes numeric. Verwende für exakte Geldbeträge NUMERIC/DECIMAL in PostgreSQL oder ganzzahlige Centbeträge in SQLite. Die Deklaration DECIMAL in SQLite erzeugt keine exakte Dezimalspeicherung. Runde Zwischenergebnisse nicht und runde für die Anzeige.
Wichtige Erkenntnisse
- Klammern steuern, welche Beträge vor einer Multiplikation oder Division kombiniert werden.
- Wandle einen Operanden vor der ganzzahligen Division um; eine Umwandlung des Ergebnisses kann verlorene Stellen nicht wiederherstellen.
- Modulo gibt einen Rest zurück, etwa die nach vollen Stunden verbleibenden Minuten.
- ROUND, FLOOR, CEIL und TRUNC behandeln einen Wert mit Nachkommateil unterschiedlich.
- Die Rundung von Gleitkommazahlen und die verfügbaren Zahlenfunktionen hängen vom Typ und von der Datenbank ab.
- Verwende für exakte Beträge eine exakte numerische Speicherung in PostgreSQL oder ganzzahlige Centbeträge in SQLite.
- NULLIF kann dafür sorgen, dass ein Divisor von null statt eines Fehlers NULL ergibt.
1.3 Werte zwischen Datentypen umwandeln
Der Datentyp eines Werts beeinflusst Berechnungen, Vergleiche und Sortierungen. Die Zahl 42 unterscheidet sich vom Text '42', auch wenn eine Ergebnistabelle beide gleich anzeigt.
Einen Wert explizit umwandeln
Zu den üblichen Typen gehören INTEGER für ganze Zahlen, NUMERIC oder DECIMAL für exakte Dezimalzahlen in PostgreSQL, REAL oder double precision für Näherungswerte, TEXT oder VARCHAR für Text sowie DATE, TIME, TIMESTAMP und BOOLEAN, sofern unterstützt.
SELECT CAST('42' AS INTEGER) AS number_value,
CAST(42 AS TEXT) AS text_value;
CAST(expression AS type) gehört zum SQL-Standard. Das erste Ergebnis ist eine Zahl, das zweite Text. PostgreSQL akzeptiert auch '42'::integer. Die Umwandlung von NULL ergibt weiterhin NULL.
Für eine Dezimaldivision schreibe in SQLite CAST(quantity AS REAL) / 4 und in PostgreSQL CAST(quantity AS NUMERIC) / 4. Die Menge 7 ergibt 1.75. CAST(7 AS NUMERIC) / 2 in SQLite ergibt weiterhin 3: NUMERIC belässt diesen ganzzahligen Wert als Ganzzahl. REAL ist für diesen Zweck die passende Umwandlung in SQLite.
Verstehen, was eine Umwandlung in eine Ganzzahl bewirkt
| Eingabe und Umwandlung | SQLite | PostgreSQL |
|---|---|---|
CAST(3.9 AS INTEGER) | 3 | 4 |
CAST(-3.9 AS INTEGER) | -3 | -4 |
CAST('abc' AS INTEGER) | 0 | Fehler |
SQLite schneidet den Nachkommateil in Richtung null ab. PostgreSQL rundet einen numerischen Wert auf die nächste ganze Zahl. Verwende zuerst ROUND, TRUNC, FLOOR oder CEIL, wenn die gewünschte Regel wichtig ist. PostgreSQL lehnt Text ab, der keine gültige Zahl ist. SQLite liest einen führenden Zahlenteil: '12abc' wird zu 12 und '12.5' wird zu 12, wenn sie in INTEGER umgewandelt werden. Eine null nach einer SQLite-Umwandlung beweist daher nicht, dass der ursprüngliche Text eine gültige null war. TRY_CAST in SQL Server gibt bei einer fehlgeschlagenen Umwandlung NULL zurück.
Mengenangaben von Kennungen unterscheiden
Text wird Zeichen für Zeichen sortiert. Die Zeichenketten '9', '10' und '100' werden als '10', '100', '9' sortiert. Um echte numerische Mengenangaben zu ordnen, die als Text gespeichert sind, verwende ORDER BY CAST(code AS INTEGER), nachdem du sichergestellt hast, dass es gültige Zahlen sind.
Eine US-Postleitzahl wie '02134' ist eine Kennung. Ihre Umwandlung ergibt 2134 und verliert die erste Null. Auch Telefonnummern gehören in Textform gespeichert: Ihre Ziffern kennzeichnen etwas, statt eine Menge zu beschreiben, die man addieren oder mitteln kann.
Automatische Umwandlungen erkennen
Sowohl SQLite als auch PostgreSQL wandeln in 'Order #' || 42 die Zahl in Text um und erzeugen 'Order #42'. Beide werten auch das Literal in Anführungszeichen in '5' + 3 als Zahl aus. In PostgreSQL hat dieses Literal zunächst einen offenen Typ; eine TEXT-Spalte hat nicht dieselbe Freiheit. Die Addition von 3 zu einer TEXT-Spalte scheitert, wandle die Spalte daher explizit um.
SQLite gibt Spalten eine Typpräferenz, die Typaffinität heißt, und kann in einer gewöhnlichen Spalte verschiedene Werttypen speichern. typeof(42), typeof(4.2), typeof('42') und typeof(NULL) melden 'integer', 'real', 'text' und 'null'. SQLite hat keinen eigenen DATE-Typ: CAST('2026-03-14' AS DATE) ergibt 2026. Verwende date('2026-03-14') für seine Datumsfunktionen.
Oracle bietet TO_NUMBER, TO_CHAR und TO_DATE. TO_CHAR und TO_DATE in PostgreSQL nehmen Formatmuster wie 'MM/DD/YYYY' entgegen. CONVERT in SQL Server verwendet einen numerischen Stilcode: CONVERT(date, '03/14/2026', 101) liest das US-Datumsformat.
Wichtige Erkenntnisse
- CAST wandelt einen Wert explizit in einen gewünschten Typ um; NULL bleibt NULL.
- SQLite schneidet bei der Umwandlung von Zahlen in Ganzzahlen den Nachkommateil ab, während PostgreSQL rundet.
- SQLite kann ungültigen numerischen Text in einen Teil einer Zahl oder in null umwandeln.
- Speichere US-Postleitzahlen und Telefonnummern als Text, damit ihre Kennung erhalten bleibt.
- Textsortierung und numerische Sortierung können unterschiedliche Reihenfolgen ergeben.
2Fehlende Werte mit NULL-Logik und COALESCE behandeln
Ein fehlender Wert kann eine Berechnung und auch die Zeilen verändern, die ein Filter behält. Um NULL zu verstehen, musst du sowohl die Daten als auch die Bedingung verfolgen, die sie verwendet. Du unterscheidest fehlende Werte von null und leerem Text, verfolgst TRUE, FALSE und UNKNOWN durch eine Abfrage und wählst Ersatzwerte, die die Bedeutung eines Berichts erhalten. Mit COALESCE und NULLIF kannst du anschließend Lücken füllen oder gezielt erzeugen.
2.1 Vorhersagen, wie sich NULL in Berechnungen und Bedingungen verhält
NULL kennzeichnet einen fehlenden oder unbekannten Wert. Eine leere Ergebniszelle kann NULL anzeigen, aber NULL ist kein gewöhnlicher Wert, den du mit = vergleichst.
Eine fehlende Eingabe durch einen Ausdruck verfolgen
Null ist eine bekannte Zahl. Leerer Text, '', ist eine bekannte Zeichenkette ohne Zeichen. Der Text 'N/A' ist eine erfasste Bezeichnung. NULL sagt aus, dass kein Wert verfügbar ist. Oracle behandelt leeren Text als NULL; SQLite und PostgreSQL unterscheiden beides.
Die meisten arithmetischen Ausdrücke und Funktionen geben eine fehlende Eingabe als NULL weiter. Bei einem Gehalt von 50.000 und einem Bonus von NULL ergibt salary + bonus den Wert NULL. Die Summe ist unbekannt, weil der Bonus unbekannt ist. Auch UPPER(NULL), ROUND(NULL, 2) und 'Ana ' || NULL geben in SQLite und PostgreSQL NULL zurück.
Direkt auf NULL prüfen
bonus = NULL, bonus <> NULL und selbst NULL = NULL ergeben UNKNOWN. Von zwei fehlenden Werten ist nicht bekannt, ob sie gleich sind. Verwende bonus IS NULL oder bonus IS NOT NULL. Diese Prüfungen geben immer TRUE oder FALSE zurück.
SQL-Bedingungen haben drei mögliche Ergebnisse: TRUE, FALSE und UNKNOWN. SQLite zeigt TRUE als 1, FALSE als 0 und UNKNOWN als NULL an.
| Bedingung | Ergebnis | Grund |
|---|---|---|
FALSE AND UNKNOWN | FALSE | Eine falsche Teilbedingung schließt AND aus |
TRUE AND UNKNOWN | UNKNOWN | Die zweite Teilbedingung ist ungeklärt |
TRUE OR UNKNOWN | TRUE | Eine wahre Alternative macht OR wahr |
FALSE OR UNKNOWN | UNKNOWN | Die verbleibende Alternative ist ungeklärt |
NOT UNKNOWN | UNKNOWN | Die Umkehrung eines unbekannten Werts klärt ihn nicht |
Verstehen, welche Zeilen WHERE behält
WHERE behält nur TRUE. Sowohl bei FALSE als auch bei UNKNOWN wird die Zeile ausgelassen. Bei Boni von 1.000, 0, NULL, 2.500 und NULL behält WHERE bonus < 1000 nur die null. WHERE bonus >= 1000 behält 1.000 und 2.500. Diese Filter erfassen drei Zeilen, nicht fünf. WHERE NOT (bonus < 1000) behält ebenfalls nur die beiden bekannten Boni von mindestens 1.000.
Dasselbe Problem betrifft <>. Bei den Städten Boston, Denver, NULL, Boston und Austin behält WHERE city <> 'Boston' Denver und Austin. Schließe die unbekannte Stadt ausdrücklich ein:
WHERE city <> 'Boston' OR city IS NULL
Dies behält drei Zeilen. NOT holt fehlende Werte nicht automatisch zurück.
Listen und Vergleiche beachten
3 IN (1, 2, NULL) ist UNKNOWN: Das fehlende Element könnte 3 sein. Bei x NOT IN (1, 2, NULL) erfüllt ein übereinstimmender Wert NOT IN nicht und jeder nicht übereinstimmende Wert ergibt UNKNOWN. In einer WHERE-Klausel behält diese feste Liste keine Zeilen. Entferne ein unbeabsichtigtes NULL aus einer Ausschlussliste, bevor du sie verwendest.
Für einen Gleichheitsvergleich, der zwei NULL-Werte als gleich behandelt, verwende a IS NOT DISTINCT FROM b. Das Gegenteil, a IS DISTINCT FROM b, ist TRUE, wenn ein Wert NULL ist und der andere nicht; zwei NULL-Werte sind nicht verschieden. PostgreSQL und SQLite ab Version 3.39 unterstützen diese Formen. SQLite hat auch IS und IS NOT; MySQL schreibt NULL-sichere Gleichheit als <=>.
Die Standardeinstellungen für die Sortierung von NULL unterscheiden sich: SQLite setzt NULL bei aufsteigender Sortierung an den Anfang, PostgreSQL ans Ende. Gib die Position an, wenn sie wichtig ist: ORDER BY bonus DESC NULLS LAST ordnet bekannte Boni absteigend und setzt fehlende Boni ans Ende.
Wichtige Erkenntnisse
- NULL bedeutet fehlend oder unbekannt, nicht null oder leerer Text.
- Vergleiche mit NULL ergeben UNKNOWN; prüfe fehlende Werte mit IS NULL.
- WHERE behält nur TRUE, daher holen NOT und <> Zeilen mit unbekanntem Ergebnis nicht zurück.
- AND und OR können ein unbekanntes Ergebnis nur auflösen, wenn die andere Bedingung das Ergebnis bestimmt.
- Ein NULL in einer NOT-IN-Liste verhindert, dass die Bedingung TRUE ist.
- IS NOT DISTINCT FROM behandelt zwei NULL-Werte als gleich.
- NULLS FIRST oder NULLS LAST legt die Sortierung ausdrücklich fest.
2.2 Fehlende Werte mit COALESCE ersetzen und mit NULLIF erzeugen
Fehlende Werte brauchen manchmal einen Ersatzwert und sollten manchmal fehlend bleiben. Diese Wahl gehört zur Bedeutung eines Berichts. COALESCE füllt eine Lücke; NULLIF verwandelt einen übereinstimmenden Platzhalterwert in eine Lücke.
Den ersten verfügbaren Wert wählen
COALESCE(a, b, ...) prüft von links nach rechts und gibt das erste Argument zurück, das nicht NULL ist. Die Funktion gibt NULL zurück, wenn alle Argumente NULL sind.
SELECT COALESCE(mobile_phone, home_phone, 'no phone') AS contact
FROM customers;
Ohne Mobilnummer und mit der Festnetznummer '555-0100' ist der Kontakt '555-0100'. Ist keine der beiden Nummern erfasst, ist er 'no phone'. Eine bekannte null oder leere Zeichenkette zählt als verfügbar: COALESCE überspringt NULL, nicht Werte, die leer oder falsch aussehen.
Für die Vergütung ergibt salary + COALESCE(bonus, 0) den Wert 50.000, wenn das Gehalt 50.000 und der Bonus NULL ist. Das ist angemessen, wenn ein fehlender Bonus bedeutet, dass keiner gezahlt wurde. Eine fehlende Produktbewertung bedeutet keine Bewertung von null; ein Ersatz würde eine schlechte Bewertung erfinden. Lasse diese Zahl fehlen oder erstelle eine Textbezeichnung für die Anzeige.
Kompatible Typen für Ersatzwerte verwenden
PostgreSQL kann das ganzzahlige rating nicht mit dem Text 'not rated' in einem numerischen Ergebnis kombinieren. Wandle die bekannten Bewertungen zuerst in Text um:
COALESCE(CAST(rating AS TEXT), 'not rated')
Eine Bewertung von 4 wird als Text '4' angezeigt; ein NULL-Wert als 'not rated'. SQLite akzeptiert gemischte numerische und Textargumente, aber die Ausgabe kann dann verschiedene Typen enthalten. Mache den gewünschten Ergebnistyp deutlich, wenn du eine Abfrage zwischen Datenbanken überträgst.
COALESCE gehört zum SQL-Standard und akzeptiert zwei oder mehr Argumente. Die üblichen Alternativen mit zwei Argumenten sind IFNULL in SQLite und MySQL, ISNULL in SQL Server und NVL in Oracle.
Einen Platzhalterwert in NULL umwandeln
NULLIF(a, b) gibt NULL zurück, wenn die Argumente gleich sind; andernfalls gibt es das erste Argument zurück. NULLIF(0, 0) ist NULL, während NULLIF(5, 0) gleich 5 ist.
Ein nützlicher Ausdruck für eine Rate ist:
orders * 100.0 / NULLIF(visits, 0) AS conversion_pct
Bei 12 Bestellungen und 300 Besuchen bleibt der Divisor 300 und die Rate ist 4.0. Bei null Besuchen wird der Divisor zu NULL und die Rate zu NULL. PostgreSQL vermeidet einen Fehler durch Division durch null, und das Ergebnis kennzeichnet die nicht definierte Rate korrekt. Würdest du diese Rate durch null ersetzen, wäre das eine andere Aussage.
Lücken bereinigen, bevor eine Bezeichnung eingesetzt wird
COALESCE(NULLIF(phone, ''), 'unknown')
Das innere NULLIF wandelt eine leere Zeichenkette in NULL um. Das äußere COALESCE bezeichnet dann sowohl ein ursprüngliches NULL als auch eine leere Zeichenkette als 'unknown'. Eine erfasste Telefonnummer wird unverändert weitergegeben.
Nimm bei einem optionalen zweiten Vornamen das nachfolgende Leerzeichen in den Ersatzwert auf:
first_name || ' ' || COALESCE(middle_name || ' ', '') || last_name
Ein zweiter Vorname mit NULL trägt nichts bei, sodass 'Ana Lopez' entsteht. Der zweite Vorname 'Maria' trägt 'Maria ' bei, sodass 'Ana Maria Lopez' entsteht.
Diese Ausdrücke ändern nur das Abfrageergebnis. Die ursprünglich gespeicherten Werte bleiben in der Tabelle. Ein Filter wie WHERE COALESCE(bonus, 0) = 0 fasst bekannte Boni von null und fehlende Boni zusammen. Verwende ihn daher, wenn du diese beiden Gruppen suchst.
Wichtige Erkenntnisse
- COALESCE gibt das erste Argument zurück, das nicht NULL ist, einschließlich einer bekannten null oder eines leeren Textes.
- Ein Ersatzwert muss die Bedeutung der fehlenden Daten ausdrücken und einen kompatiblen Typ haben.
- NULLIF gibt bei Gleichheit NULL und andernfalls sein erstes Argument zurück.
- Verwende NULLIF um einen Divisor, damit ein Nenner von null NULL ergibt.
- Bereinige einen Platzhalterwert mit NULLIF, bevor du mit COALESCE einen Ersatzwert für die Anzeige einsetzt.
3Texte mit Zeichenkettenfunktionen bereinigen, verbinden und zerlegen
Text aus einer Tabelle braucht oft eine nutzbare Form: einen vollständigen Namen, eine einheitliche E-Mail-Adresse oder einen Teil eines Codes. SQL kann Zeichenketten verketten und bereinigen, ihre Zeichen zählen und den Teil vor oder nach einem Trennzeichen extrahieren. Du verfolgst die Zeichenpositionen durch jeden Schritt und prüfst, wie sich Leerzeichen, Groß- und Kleinschreibung sowie NULL auf das Ergebnis auswirken. SQLite und PostgreSQL teilen viele Funktionen, unterscheiden sich aber bei mehreren Namen und Verhaltensweisen.
3.1 Textwerte verketten und bereinigen
SQL behandelt einen Textwert als Zeichenkette. Textfunktionen können einen vollständigen Namen erstellen oder eine E-Mail-Adresse für einen Vergleich bereinigen. Ihre Ergebnisse erscheinen in der Abfrage; gespeicherter Text bleibt unverändert.
Text schreiben und verketten
Textliterale stehen in einfachen Anführungszeichen. Um einen Apostroph einzufügen, verdopple ihn: 'O''Brien' steht für „O'Brien“. Ein Paar einfacher Anführungszeichen, '', ist eine leere Zeichenkette.
SELECT first_name || ' ' || last_name AS full_name
FROM customers;
Der Verkettungsoperator || verbindet die Teile genau wie geschrieben. Bei 'Ana' und 'Lopez' ist das Ergebnis 'Ana Lopez'. Das mittlere Literal liefert das Leerzeichen; die Verkettung fügt es nicht automatisch ein.
SQLite, PostgreSQL und Oracle verwenden ||. Das standardmäßige || von MySQL bedeutet OR, verwende dort also CONCAT. SQL Server verwendet + und unterstützt ab 2025 auch ||. Um eine numerische Bestell-ID einzufügen, wandeln SQLite und PostgreSQL sie in 'Order #' || order_id in Text um. Wandle bei + in SQL Server die Zahl zuerst um: 'Order #' + CAST(order_id AS VARCHAR(10)).
Wählen, wie ein fehlender Teil verknüpft wird
In SQLite und PostgreSQL macht ein NULL-Operand ein Ergebnis mit || zu NULL. Oracle behandelt diesen fehlenden Teil als leeren Text. Auch CONCAT unterscheidet sich je nach Datenbank:
| Datenbank | CONCAT('Ana', NULL, 'Lopez') |
|---|---|
| PostgreSQL, SQL Server, SQLite ab 3.44 | 'AnaLopez' |
| MySQL | NULL |
CONCAT in Oracle nimmt genau zwei Argumente entgegen. CONCAT_WS(' ', first_name, middle_name, last_name) setzt Leerzeichen zwischen Teile, die nicht NULL sind, sodass ein fehlender zweiter Vorname 'Ana Lopez' ergibt. SQLite hat CONCAT und CONCAT_WS in 3.44 hinzugefügt. Das Überspringen von NULL entfernt jedoch keine leere Zeichenkette.
Groß- und Kleinschreibung ändern und Ränder bereinigen
UPPER('boston') ergibt 'BOSTON'; LOWER erzeugt Kleinbuchstaben. INITCAP('ana LOPEZ') in PostgreSQL ergibt 'Ana Lopez'. SQLite hat kein INITCAP und seine eingebaute Umwandlung der Groß- und Kleinschreibung ändert nur A bis Z: UPPER('é') bleibt ohne die ICU-Erweiterung 'é'. PostgreSQL richtet sich bei der Umwandlung nach seinen Regionaleinstellungen.
TRIM entfernt Leerzeichen an beiden Enden; LTRIM entfernt sie nur am Anfang und RTRIM nur am Ende. TRIM(' New York ') ergibt 'New York' und behält die beiden Leerzeichen im Inneren. Um x an beiden Enden zu entfernen, schreibt SQLite TRIM('xxBostonxx', 'x'); PostgreSQL schreibt TRIM(BOTH 'x' FROM 'xxBostonxx').
Zeichen ersetzen und Bereinigungsschritte verschachteln
REPLACE('555-0100', '-', '') ergibt '5550100'. Die Funktion ersetzt jedes genaue Vorkommen. Die Groß- und Kleinschreibung ist wichtig: Das Ersetzen von 'st' in 'Main St' ändert nichts, weil 'St' ein großes S hat.
SELECT LOWER(TRIM(email)) AS email_clean
FROM customers;
Für ' Ana@Example.COM ' erzeugt TRIM zuerst 'Ana@Example.COM', dann erzeugt LOWER 'ana@example.com'. Verschachtelung bedeutet, dass die innerste Funktion die Eingabe der nächsten liefert.
Gewöhnliche Textgleichheit unterscheidet in SQLite und PostgreSQL standardmäßig zwischen Groß- und Kleinschreibung. WHERE LOWER(TRIM(email)) = 'ana@example.com' kann unterschiedlich großgeschriebene Eingaben mit Leerzeichen an den Rändern abgleichen. Die Standardsortierfolge von MySQL ignoriert die Groß- und Kleinschreibung, und LIKE in SQLite ignoriert sie bei A bis Z, obwohl der standardmäßige Vergleich mit = dies nicht tut.
Wichtige Erkenntnisse
- Verwende einfache Anführungszeichen für Text und verdopple einen Apostroph innerhalb eines Literals.
- Die Verkettung verbindet die Teile genau; füge Trennzeichen ausdrücklich ein.
- Das Verhalten bei NULL unterscheidet sich zwischen ||, CONCAT und den Datenbankdialekten.
- TRIM entfernt Leerzeichen an den Rändern, während REPLACE übereinstimmende Zeichen im gesamten Text ändert.
- Verschachtelte Funktionen werden von innen nach außen ausgeführt.
- Die Umwandlung der Groß- und Kleinschreibung und deren Berücksichtigung beim Abgleich hängen von der Datenbank und den Regionaleinstellungen ab.
3.2 Textlängen bestimmen und Textteile extrahieren
Textfunktionen finden und schneiden Teile anhand ihrer Zeichenposition aus. In SQL beginnen Positionen bei 1, das erste Zeichen steht also an Position 1. Eine gefundene Position und eine Zeichenanzahl sind unterschiedliche Eingaben.
Eine Zeichenkette messen und zerlegen
LENGTH('Boston') ergibt 6. Leerzeichen zählen mit: LENGTH(' Bo ') ergibt 4. Leerer Text hat die Länge 0; LENGTH(NULL) ist NULL. LENGTH in MySQL zählt Bytes, verwende dort also CHAR_LENGTH für Zeichen. SQL Server verwendet LEN, das abschließende Leerzeichen ignoriert.
SELECT SUBSTR('Boston', 1, 3) AS beginning,
SUBSTR('Boston', 4) AS ending;
Die Ergebnisse sind 'Bos' und 'ton'. Der erste Aufruf nimmt drei Zeichen ab Position 1. Der zweite lässt die Anzahl weg und nimmt alles ab Position 4. PostgreSQL schreibt auch SUBSTRING('Boston' FROM 4 FOR 3). SQLite akzeptiert SUBSTRING ab Version 3.34 als Namen. SQL Server verwendet SUBSTRING(text, start, count); die Anzahl ist bis einschließlich 2022 erforderlich und ab 2025 optional.
SQLite kann von rechts zählen: SUBSTR('Boston', -3) ergibt 'ton'. Negative Startwerte in PostgreSQL zählen nicht vom Ende rückwärts. Verwende dort RIGHT('Boston', 3); LEFT entnimmt Zeichen vom Anfang. SQLite hat weder LEFT noch RIGHT.
Die Trennstelle finden
INSTR(text, search) in SQLite gibt die Position des ersten Treffers zurück. PostgreSQL verwendet STRPOS oder POSITION(search IN text). Diese Funktionen geben 0 zurück, wenn kein Treffer gefunden wird. Die Suche unterscheidet Groß- und Kleinschreibung: INSTR('Ana', 'a') ergibt 3.
Bei 'ana@example.com' steht das @ an Position 4. Der Benutzername endet direkt davor; die Domain beginnt direkt danach:
SUBSTR(email, 1, INSTR(email, '@') - 1) AS user_name,
SUBSTR(email, INSTR(email, '@') + 1) AS domain
Der erste Ausdruck wird zu SUBSTR(email, 1, 3) und ergibt 'ana'. Der zweite beginnt bei 5 und ergibt 'example.com'. Lässt du - 1 weg, wird @ in den Benutzernamen aufgenommen. Lässt du + 1 weg, steht es am Anfang der Domain. Ersetze in PostgreSQL INSTR durch STRPOS oder verwende SPLIT_PART(email, '@', 2) für die Domain.
Ein fehlendes Trennzeichen behandeln
Für 'anaexample.com' gibt INSTR 0 zurück. Die Formel für die Domain beginnt bei 1 und gibt irreführenderweise die ganze Zeichenkette zurück. Die Formel für den Benutzernamen ergibt in SQLite leeren Text; PostgreSQL lehnt ihre negative Länge für die Teilzeichenkette ab. Sichere die Extraktion ab:
CASE
WHEN INSTR(email, '@') > 0
THEN SUBSTR(email, INSTR(email, '@') + 1)
END
Dies gibt NULL zurück, wenn das Trennzeichen fehlt. Die Absicherung prüft auf ein Trennzeichen, nicht alle Regeln für eine gültige E-Mail-Adresse.
Kurze Bezeichnungen und Codes mit fester Breite erstellen
SUBSTR(first_name, 1, 1) || '. ' || last_name ergibt für Ana Lopez 'A. Lopez'. WHERE LENGTH(zip_code) <> 5 findet erfasste US-Postleitzahlen als Zeichenketten mit falscher Länge; NULL-Längen ergeben UNKNOWN und werden ausgelassen.
LPAD('42', 5, '0') in PostgreSQL ergibt '00042'; RPAD füllt rechts auf. SQLite kann diesen Code mit SUBSTR('00000' || 42, -5) erstellen. Da nur fünf Zeichen behalten werden, wird ein längerer Wert auch abgeschnitten. Dieser Ausdruck für eine feste Breite braucht daher einen passenden Code.
Wichtige Erkenntnisse
- Positionen in SQL-Zeichenketten beginnen bei 1; LENGTH zählt Leerzeichen mit.
- SUBSTR nimmt eine Startposition und eine optionale Zeichenanzahl entgegen.
- INSTR, STRPOS und POSITION geben 0 zurück, wenn kein Treffer vorhanden ist.
- Verwende vor einem Trennzeichen die Position minus 1 und danach die Position plus 1.
- Prüfe vor dem Extrahieren eines Teils, ob das Trennzeichen fehlt.
- Das Extrahieren vom Ende und das Auffüllen haben in SQLite und PostgreSQL unterschiedliche Namen.
4Mit Datums- und Zeitwerten arbeiten
Die Arbeit mit Datumswerten beginnt mit einer klaren Unterscheidung zwischen einem Kalendertag, einer Uhrzeit und einem Zeitstempel. Darauf aufbauend kann SQL Monatsbezeichnungen erstellen, Fristen berechnen, verstrichene Zeit messen und einen vollständigen Zeitraum filtern. Du hältst Datumswerte und Anzeigetext auseinander, berücksichtigst Monatsenden und Geburtstage und vergleichst die SQLite- und PostgreSQL-Ausdrücke für dieselbe Aufgabe. Grenzfälle machen diese Berechnungen zuverlässig.
4.1 Datums- und Zeitwerte schreiben, speichern und lesen
Mit einem Datum lässt sich leichter rechnen, wenn seine Speicherung und Schreibweise klar sind. Der Text '03/04/2026' könnte den 4. März oder den 3. April bedeuten. Ein ISO-Datum, '2026-03-14', bringt Jahr, Monat und Tag in eine eindeutige Reihenfolge.
Den Wert dem passenden Typ zuordnen
PostgreSQL hat DATE für einen Kalendertag, TIME für eine Uhrzeit und TIMESTAMP für Datum und Uhrzeit. Sein TIMESTAMP WITH TIME ZONE, auch timestamptz genannt, speichert einen Zeitpunkt in UTC und zeigt ihn in der Zeitzone der Sitzung an. Ein einfacher TIMESTAMP trägt diese Zeitzonenbedeutung nicht.
SQLite speichert Datums- und Zeitwerte als ISO-Text oder als Zahlen, nicht in eigenen Datums- und Zeittypen. Zu den numerischen Formen gehören julianische Tageszahlen und die Unixzeit. Die Datumsfunktionen interpretieren diese Werte und geben ein Datum, eine Uhrzeit oder einen numerischen Wert zurück.
Verwende ISO-Text mit fester Breite wie '2026-03-14', einschließlich führender Nullen. Füge eine Uhrzeit im 24-Stunden-Format hinzu: '2026-03-14 09:30:00'. Das typisierte Literal DATE '2026-03-14' in PostgreSQL erzeugt ausdrücklich einen Datumswert.
Die zeitliche Reihenfolge erhalten
ISO-Text mit fester Breite wird in zeitlicher Reihenfolge verglichen, weil er mit dem größten Bestandteil beginnt. '2026-03-14' kommt vor '2026-11-02'. Anzeigetext im US-Format hat diese Eigenschaft nicht: Als Zeichenketten wird '11/02/2025' nach '03/14/2026' sortiert, obwohl das Datum früher liegt.
Die Einlesefunktion von SQLite benötigt das unterstützte Format. date('2026-3-14') gibt NULL zurück, weil der Monat nicht zweistellig ist. Sie kann auch ein unmögliches Datum normalisieren: date('2026-02-30') gibt '2026-03-02' zurück. Ein Ergebnis, das nicht NULL ist, beweist allein nicht, dass die Eingabe ein gültiger Kalendertag war. PostgreSQL lehnt DATE '2026-02-30' ab.
Text in einem anderen Format einlesen
PostgreSQL und Oracle verwenden TO_DATE('03/14/2026', 'MM/DD/YYYY'), um ein US-Format einzulesen. PostgreSQL liest ISO-Text auch mit CAST('2026-03-14' AS DATE) oder '2026-03-14'::date.
SQLite hat keine Einlesefunktion TO_DATE. Setze bei Text mit festem Format MM/DD/YYYY in d den ISO-Text neu zusammen:
SUBSTR(d, 7, 4) || '-' ||
SUBSTR(d, 1, 2) || '-' || SUBSTR(d, 4, 2)
Die Teile sind das Jahr '2026', der Monat '03' und der Tag '14'. Das Ergebnis ist '2026-03-14', was die Datumsfunktionen von SQLite lesen können. Die Positionen setzen voraus, dass die Eingabe tatsächlich das feste Format verwendet.
Das aktuelle Datum und die aktuelle Uhrzeit ermitteln
CURRENT_DATE und CURRENT_TIMESTAMP funktionieren in SQLite und PostgreSQL. SQLite gibt UTC-Text zurück; date('now', 'localtime') liefert das lokale Datum. Um Mitternacht können UTC und das lokale Kalenderdatum voneinander abweichen.
PostgreSQL verwendet die Zeitzone der Sitzung. CURRENT_TIMESTAMP und NOW() geben den Beginn der aktuellen Transaktion wieder; durch Warten innerhalb dieser Transaktion ändert sich ihr Wert also nicht. MySQL bietet NOW() und CURDATE(); SQL Server hat GETDATE() und SYSDATETIME(); Oracle hat SYSDATE, das eine Uhrzeit enthält, und CURRENT_DATE.
Um eine Fälligkeitsberechnung zu prüfen, verwende zunächst einen festen Bezugspunkt wie DATE '2026-10-21' in PostgreSQL oder '2026-10-21' in SQLite. Dann kannst du das Ergebnis mit einem Kalender vergleichen, ohne dass es sich am nächsten Tag ändert.
Wichtige Erkenntnisse
- DATE ist ein Kalendertag; TIMESTAMP fügt eine Uhrzeit hinzu.
- Verwende YYYY-MM-DD mit fester Breite für übertragbaren, eindeutigen Datumstext.
- ISO-Text wird zeitlich geordnet sortiert, wenn Format und Zeitbasis einheitlich sind.
- Ein Datumsergebnis von SQLite kann eine unmögliche Eingabe normalisieren, statt sie abzulehnen.
- Funktionen für das aktuelle Datum folgen unterschiedlichen Zeitzonen- und Transaktionsregeln.
4.2 Bestandteile von Datumswerten extrahieren und formatieren
Extrahiere einen Datumsbestandteil, wenn du ein Jahr oder einen Wochentag für eine Berechnung brauchst. Formatiere ein Datum, wenn du Text für einen Leser brauchst. Diese Vorgänge können unterschiedliche Typen erzeugen, auch wenn die angezeigten Zeichen gleich aussehen.
Jahr, Monat oder Wochentag extrahieren
PostgreSQL verwendet das standardisierte EXTRACT(part FROM value). Für DATE '2026-03-14' ergibt die Extraktion von YEAR den Wert 2026 und die von MONTH den Wert 3, beide als Zahlen. MySQL und Oracle unterstützen EXTRACT ebenfalls.
SQLite verwendet strftime(format, value), das Text zurückgibt:
| SQLite-Muster | Ergebnis für '2026-03-14' |
|---|---|
'%Y' | '2026' |
'%m' | '03' |
'%d' | '14' |
'%w' | '6' |
%w in SQLite und DOW in PostgreSQL nummerieren die Tage von Sonntag mit 0 bis Samstag mit 6. Der 14. März 2026 ist ein Samstag. ISODOW in PostgreSQL nummeriert dagegen von Montag mit 1 bis Sonntag mit 7. Ein Wochenendfilter in SQLite ist WHERE strftime('%w', order_date) IN ('0', '6').
Die richtigen Typen vergleichen
strftime('%m', order_date) = 3 ist in SQLite für ein Datum im März falsch: Die Funktion gibt den Text '03' zurück, nicht die Zahl 3. Vergleiche ihn mit = '03' oder wandle ihn zuerst um:
CAST(strftime('%m', order_date) AS INTEGER) = 3
Dies ist auch im Quartalsausdruck (CAST(strftime('%m', d) AS INTEGER) + 2) / 3 nützlich. Die ganzzahlige Division ergibt Quartal 1 für März und Quartal 4 für November. PostgreSQL hat direkt EXTRACT(QUARTER FROM d).
Einen Monat als ganzen Zeitraum bestimmen
strftime('%Y-%m', order_date) erstellt in SQLite eine Bezeichnung wie '2026-03'. date(order_date, 'start of month') erzeugt '2026-03-01'. PostgreSQL kann TO_CHAR(order_date, 'YYYY-MM') für eine Bezeichnung oder DATE_TRUNC('month', order_date) für den ersten Zeitpunkt dieses Monats verwenden.
Behalte das Jahr in einer Zeitraumsbezeichnung. Ein einzelner Monatswert 3 würde den März verschiedener Jahre zusammenfassen. Der Wert für den Monatsersten kann zum Rechnen und Sortieren dienen, während ein separater Ausdruck die Anzeige liefert.
Bei der Ausgabe formatieren
In PostgreSQL ergibt TO_CHAR(DATE '2026-03-14', 'MM/DD/YYYY') den Wert '03/14/2026', und das Muster 'Mon DD, YYYY' ergibt 'Mar 14, 2026'. Oracle verwendet diese Muster ebenfalls. Das US-Format in SQLite lautet strftime('%m/%d/%Y', '2026-03-14').
Die Musterzeichen gehören zum jeweiligen Datenbanksystem. MM in PostgreSQL bedeutet Monat und MI Minute. %m in SQLite bedeutet Monat und %M Minute; änderst du die Großschreibung, ändert sich die abgefragte Information.
SELECT TO_CHAR(order_date, 'MM/DD/YYYY') AS order_day
FROM orders
ORDER BY order_date;
Hier zeigt PostgreSQL lesbaren Text an, sortiert aber die tatsächlichen Datumswerte. Eine Sortierung nach order_day würde die angezeigten Zeichenketten zuerst nach Monat sortieren und könnte Datumswerte verschiedener Jahre in die falsche Reihenfolge bringen.
Wichtige Erkenntnisse
- EXTRACT in PostgreSQL gibt numerische Bestandteile zurück; strftime in SQLite gibt Text zurück.
- Vergleiche einen SQLite-Monat mit führender Null mit Text oder wandle ihn in eine Zahl um.
- Die Nummerierung der Wochentage hängt von der gewählten Konvention ab.
- Behalte das Jahr in Monatsbezeichnungen und formatiere nur für die Anzeige.
4.3 Mit Datumswerten rechnen und nach Datumsbereichen filtern
Beim Rechnen mit Kalenderdaten musst du Monatslängen, Zeitanteile und die benötigte Art des Ergebnisses berücksichtigen. Eine Anzahl von Tagen, ein Kalendermonat und ein vollendetes Lebensjahr sind unterschiedliche Maße.
Tage und Kalendermonate addieren
PostgreSQL schreibt DATE '2026-03-14' + 30; SQLite schreibt date('2026-03-14', '+30 days'). Beide ergeben den 13. April: 17 Tage schließen den März ab und weitere 13 reichen bis zum 13. April. Der direkte Ausdruck '2026-03-14' + 30 in SQLite ergibt dagegen 2056, weil die arithmetische Operation die führende Jahreszahl als Zahl liest.
Für Monatsenden braucht man eine ausdrückliche Regel. DATE '2026-01-31' + INTERVAL '1 month' in PostgreSQL ergibt den 28. Februar um Mitternacht und verwendet damit den letzten verfügbaren Tag. date('2026-01-31', '+1 month') in SQLite rechnet überschüssige Tage in den März weiter und ergibt '2026-03-03'. Füge ab SQLite 3.46 nach der Verschiebung 'floor' hinzu, um '2026-02-28' zu wählen. ADD_MONTHS in Oracle geht ebenfalls zum letzten Tag des kürzeren Monats.
Verstrichene Zeit messen
Die Subtraktion von DATE-Werten in PostgreSQL gibt ganze Tage zurück: DATE '2026-04-13' - DATE '2026-03-14' ergibt 30. SQLite subtrahiert numerische Tageswerte: julianday('2026-04-13') - julianday('2026-03-14') ergibt 30.0. SQL Server verwendet DATEDIFF(day, start, end); MySQL verwendet DATEDIFF(end, start).
Für Zeitstempel vom 14. März um 09:30 Uhr bis 18:00 Uhr ergibt die Subtraktion in PostgreSQL ein Intervall von 08:30:00; EXTRACT(EPOCH FROM interval) / 3600 drückt es als 8,5 Stunden aus. Ab SQLite 3.38 kannst du schreiben:
(unixepoch('2026-03-14 18:00') -
unixepoch('2026-03-14 09:30')) / 3600.0
Dies ergibt 8.5. Eine mit 24 multiplizierte Differenz julianischer Tageszahlen kann wegen der Gleitkommanäherung 8.49999999627471 ergeben; runde die Anzeige. Eine Zeitstempeldauer mit Nachkommateil sollte nicht in INTEGER umgewandelt werden, bevor die gewünschte Einheit berechnet ist.
Vollendete Geburtstage zählen
Eine am 2. November 1990 geborene Person ist am 21. Oktober 2026 35 Jahre alt. Die Jahreszahlen unterscheiden sich um 36, aber der Geburtstag steht noch bevor. PostgreSQL verwendet EXTRACT(YEAR FROM AGE(DATE '2026-10-21', DATE '1990-11-02')) und liefert 35.
SQLite zieht eins ab, wenn der Geburtstag in diesem Jahr noch bevorsteht:
strftime('%Y', '2026-10-21') - strftime('%Y', birth_date)
- (strftime('%m-%d', '2026-10-21') < strftime('%m-%d', birth_date))
Der Vergleich ergibt 1, wenn der Geburtstag noch bevorsteht, und sonst 0. Die vergangenen Tage durch 365 zu teilen, ist unzuverlässig: Am 1. November 2026 hat diese Person 13.148 Tage gelebt, was durch 365 geteilt 36,02 ergibt, obwohl der 36. Geburtstag erst morgen ist. DATEDIFF in SQL Server zählt Zeitgrenzen: Der Übergang vom 31. Dezember zum 1. Januar zählt als Jahresgrenze, nicht als vollendetes Lebensjahr.
Jeden Zeitstempel eines Zeitraums einschließen
BETWEEN schließt beide Bereichsgrenzen ein. Bei DATE-Spalten erfasst der 1. bis 31. März den März. Bei Zeitstempeln bedeutet eine Obergrenze von '2026-03-31' Mitternacht zu Beginn des letzten Tages und lässt den Rest dieses Tages aus.
WHERE ordered_at >= '2026-03-01'
AND ordered_at < '2026-04-01'
Dieser halboffene Bereich schließt den Beginn ein und den Beginn des nächsten Zeitraums aus. So erfasst er jede Uhrzeit im März, ohne einen letzten Sekundenbruchteil wählen zu müssen.
Überfällige Daten erfüllen due_date < CURRENT_DATE. Die Untergrenze für die letzten 30 Tage ist in PostgreSQL CURRENT_DATE - 30 und in SQLite date('now', '-30 days'). Die Tage bis zu einer Frist sind für DATE-Werte in PostgreSQL due_date - CURRENT_DATE und in SQLite julianday(due_date) - julianday(date('now')).
Wichtige Erkenntnisse
- Verwende Datumsfunktionen oder typisierte Datumswerte, keine arithmetischen Operationen auf Datumstext in SQLite.
- Entscheide, wie beim Addieren eines Monats ein Tag behandelt werden soll, der im nächsten Monat fehlt.
- Differenzen von DATE-Werten zählen Tage; Zeitstempeldifferenzen können Bruchteile enthalten.
- Das Lebensalter zählt vollendete Geburtstage, nicht vergangene Tage geteilt durch 365.
- Ein halboffener Zeitstempelbereich schließt den Beginn des Zeitraums ein und den nächsten Beginn aus.
- Verwende für Fristberechnungen in ganzen Tagen einen aktuellen Wert ohne Uhrzeit.
5Zeilen mit CASE-Ausdrücken klassifizieren
Ein Bericht braucht oft eine Regel, die Daten in eine Bezeichnung oder eine Gebühr umwandelt: eine kleine Bestellung, einen ausstehenden Versand oder einen Prioritätsrang. CASE drückt diese Auswahl innerhalb einer Abfrage aus. Du verfolgst, welche Bedingung zum Zuge kommt, ordnest exakte Grenzwerte und fehlende Werte der richtigen Kategorie zu und übersetzt Codes mit einfachen CASE-Ausdrücken. Der abschließende Bericht kombiniert die Klassifizierung mit arithmetischen Ausdrücken, Text, Datumswerten und Ersatzwerten und prüft jede Ausgabe anhand bekannter Zeilen.
5.1 Zeilen mit CASE-Suchausdrücken in Kategorien einteilen
Ein CASE-Ausdruck wählt für jede Zeile ein Ergebnis. Damit kannst du einen Preisbereich bezeichnen, eine Gebühr berechnen oder einen Datensatz markieren, der Aufmerksamkeit benötigt.
Die Suchform lesen
CASE
WHEN total < 50 THEN 'small'
WHEN total < 200 THEN 'medium'
ELSE 'large'
END AS size_band
Jedes WHEN liefert eine Bedingung und THEN den Wert, der zurückgegeben wird, wenn diese Bedingung TRUE ist. Die Datenbank prüft von oben nach unten und nimmt die erste wahre Bedingung. END schließt den Ausdruck; darauf kann ein Alias folgen. Ist keine Bedingung TRUE und fehlt ELSE, ist das Ergebnis NULL.
Eine Summe von 35 erfüllt die erste Bedingung und wird zu 'small'. Eine Summe von 50 erfüllt die erste nicht, aber die zweite, und wird zu 'medium'. Dasselbe gilt für 199,99. Eine Summe von 200 erreicht ELSE und wird zu 'large'.
Reihenfolge und Grenzen an die Regel anpassen
Der zweite Zweig braucht kein total >= 50: Ein Wert unter 50 hat bereits im ersten Zweig ein Ergebnis erhalten. Aufsteigende Schwellenwerte mit < funktionieren, weil frühere Zweige die kleineren Werte bereits erfassen. Absteigende Schwellenwerte mit >= können aus demselben Grund funktionieren.
Steht WHEN total < 200 zuerst, ist ein späterer Zweig mit < 50 nicht erreichbar. Eine Summe von 35 erfüllt bereits < 200, sodass die Prüfung dort endet. CASE wählt weder die spezifischste Bedingung noch prüft es, welche Bezeichnung am besten klingt.
Vergleiche die Geschäftsregel mit jeder Bereichsgrenze. < 50 ordnet genau 50 dem mittleren Bereich zu; <= 50 ordnet den Wert dem kleinen Bereich zu. Prüfe 49,99, 50, 199,99 und 200, um beide Seiten und die Grenzen zu betrachten. Sind Bedingungen als ausdrückliche Intervalle geschrieben, stimme ihre Grenzen ohne Lücke oder unbeabsichtigte Überlappung aufeinander ab.
NULL vor gewöhnlichen Bereichen behandeln
Eine NULL-Summe macht beide Vergleiche zu UNKNOWN. Im ersten Ausdruck erreicht sie daher ELSE und wird zu 'large', was irreführend ist. Erfasse fehlende Werte zuerst:
CASE
WHEN total IS NULL THEN 'unknown'
WHEN total < 50 THEN 'small'
WHEN total < 200 THEN 'medium'
ELSE 'large'
END
ELSE bedeutet „keine Bedingung war wahr“ und kann daher sowohl fehlende Eingaben als auch bekannte Werte außerhalb der geprüften Bereiche erfassen.
Einen einheitlichen Werttyp zurückgeben
PostgreSQL benötigt kompatible THEN- und ELSE-Typen. CASE WHEN quantity > 0 THEN unit_price ELSE 'n/a' END scheitert, wenn unit_price numerisch ist, weil 'n/a' nicht in eine Zahl umgewandelt werden kann. Verwende NULL für ein nicht verfügbares numerisches Ergebnis oder wandle den Preis in Text um, wenn die gesamte Ausgabe eine Anzeigebezeichnung ist. SQLite erlaubt gemischte Ergebnistypen, was spätere Berechnungen erschweren kann.
Eine Bedingung kann Spalten kombinieren:
CASE
WHEN country = 'US' AND subtotal >= 100 THEN 0
ELSE 7.99
END AS shipping_fee
Die zurückgegebene Gebühr kann in subtotal + CASE ... END AS amount_due stehen. Ein CASE-Ausdruck ist ein Wertausdruck und kein Befehl, der mehrere Spalten ändert; jede Ergebnisspalte braucht ihren eigenen Ausdruck.
CASE kann auch eine Division auf Zeilenebene absichern: CASE WHEN visits = 0 THEN NULL ELSE orders * 100.0 / visits END. Eine Zeile mit null wählt den NULL-Zweig. orders * 100.0 / NULLIF(visits, 0) drückt dieselbe Regel für eine fehlende Rate kürzer aus.
Wichtige Erkenntnisse
- CASE gibt den Wert der ersten Bedingung zurück, die TRUE ist.
- Ordne überlappende Bereichsbedingungen so an, dass eine breite Prüfung keine engere verdeckt.
- Wähle < oder <=, um eine exakte Grenze dem gewünschten Bereich zuzuordnen.
- Prüfe NULL vor einem Bereich ausdrücklich, wenn ELSE den Wert nicht bezeichnen soll.
- Halte Ergebnistypen kompatibel und verwende CASE überall dort, wo ein Wertausdruck passt.
5.2 Einfache CASE-Ausdrücke nutzen und CASE an verschiedenen Stellen einer Abfrage einsetzen
Die Form des einfachen CASE-Ausdrucks übersetzt einen Wert in einen anderen. Ein CASE-Suchausdruck prüft Bedingungen; ein einfacher CASE-Ausdruck vergleicht denselben Ausdruck mit einer Reihe von Werten.
Codes mit einem einfachen CASE-Ausdruck übersetzen
CASE status
WHEN 'S' THEN 'Shipped'
WHEN 'P' THEN 'Pending'
WHEN 'C' THEN 'Canceled'
ELSE 'Other'
END AS status_label
Die enthaltenen Prüfungen sind status = 'S', dann status = 'P' und dann status = 'C'. Ein Status außerhalb dieser Codes erhält 'Other'. Die Suchform kann dieselben Gleichheitsprüfungen ausdrücklich schreiben. Wähle einen CASE-Suchausdruck für Bereiche, LIKE-Muster, NULL-Prüfungen oder Bedingungen über mehrere Spalten.
CASE region WHEN NULL THEN 'missing' ELSE region END kann eine Region mit NULL nicht erfassen. Das enthaltene region = NULL ist UNKNOWN, sodass die Zeile ELSE erreicht und NULL bleibt. Schreibe CASE WHEN region IS NULL THEN 'missing' ELSE region END.
Einen benutzerdefinierten Sortierrang zuweisen
Die alphabetische Reihenfolge der Prioritäten lautet high, low, medium. Um nach Dringlichkeit zu sortieren, übersetze die Bezeichnungen in Zahlen:
SELECT ticket_id, priority
FROM tickets
ORDER BY CASE priority
WHEN 'high' THEN 1
WHEN 'medium' THEN 2
WHEN 'low' THEN 3
ELSE 4
END;
Die aufsteigende Reihenfolge setzt nun high vor medium und medium vor low; andere oder fehlende Werte stehen zuletzt. Der CASE-Ausdruck ist ein Sortierausdruck und muss keine angezeigte Spalte sein. DESC würde die numerische Rangfolge umkehren.
Ein numerisches Flag erstellen
CASE WHEN discount_pct > 0 THEN 1 ELSE 0 END AS is_discounted
Ein positiver Prozentsatz erhält 1; eine bekannte null erhält 0. Ein NULL-Prozentsatz erhält ebenfalls 0, weil > 0 UNKNOWN ist und ELSE ihn erfasst. Dieses Flag bedeutet daher „ein positiver Rabatt ist erfasst“. Es erhält nicht die Unterscheidung zwischen keinem Rabatt und einem unbekannten Rabatt. Wird diese Unterscheidung benötigt, füge einen IS-NULL-Zweig mit eigenem Ergebnis hinzu.
Flags können ausgewählt, sortiert, gefiltert oder in arithmetische Ausdrücke aufgenommen werden. Wiederhole in einer übertragbaren WHERE-Klausel den Ausdruck oder verwende seine ursprüngliche Bedingung, statt auf einen neu definierten Ausgabealias zu verweisen.
Verwandte bedingte Funktionen erkennen
COALESCE(bonus, 0) ist eine Kurzform von CASE WHEN bonus IS NOT NULL THEN bonus ELSE 0 END. NULLIF(a, b) entspricht CASE WHEN a = b THEN NULL ELSE a END. Ihre Namen vermitteln diese üblichen Zwecke direkt.
SQLite ab 3.32 und SQL Server haben IIF(condition, true_value, false_value); MySQL hat IF. DECODE in Oracle übersetzt Gleichheitstreffer, zum Beispiel DECODE(status, 'S', 'Shipped', 'P', 'Pending', 'Other'). Anders als die Gleichheitsvergleiche im einfachen CASE-Ausdruck behandelt DECODE zwei NULL-Werte als gleich. Das standardisierte CASE funktioniert in allen diesen Systemen.
Ein CASE-Ausdruck kann einen weiteren CASE-Ausdruck enthalten, aber kombinierte Bedingungen machen einen nicht verschachtelten Ausdruck oft klarer. Eine Versandregel kann direkt WHEN country = 'US' AND subtotal >= 100 THEN 0 angeben und so die Prüfungen für Land und Zwischensumme zusammenhalten.
Wichtige Erkenntnisse
- Ein einfacher CASE-Ausdruck vergleicht einen Ausdruck auf Gleichheit mit mehreren Werten.
- Verwende einen CASE-Suchausdruck für NULL-Prüfungen, Bereiche und kombinierte Bedingungen.
- Ein numerischer CASE-Ausdruck in ORDER BY erstellt eine benutzerdefinierte Rangfolge.
- Ein Flag mit ELSE 0 weist auch dann null zu, wenn seine Bedingung UNKNOWN ist.
- COALESCE und NULLIF drücken häufige Sonderfälle von CASE aus.
- DECODE in Oracle behandelt zwei NULL-Werte als gleich; ein einfacher CASE-Ausdruck tut dies nicht.
5.3 Funktionen zu einer vollständigen Berichtsabfrage kombinieren
Ein Bericht kann in einem SELECT Namen bereinigen, Nettobeträge berechnen, Monate bestimmen und die Versandgeschwindigkeit bezeichnen. Erstelle jeden Ausdruck aus seinen Eingaben und prüfe das Ergebnis, bevor du ihn mit den anderen kombinierst.
Mit bekannten Zeilen arbeiten
Eine Bestelltabelle enthält diese Datensätze. Die Datumswerte sind für die folgende SQLite-Abfrage ISO-Text; quantity ist eine Ganzzahl und unit_price numerisch.
| Bestellung | Kunde | Menge | Preis | Rabatt % | Bestellt | Versandt |
|---|---|---|---|---|---|---|
| 1001 | Ana Lopez | 3 | 12,50 | 10 | 2026-03-14 | 2026-03-17 |
| 1002 | Ben Okafor | 1 | 240,00 | 0 | 2026-03-30 | NULL |
| 1003 | Chen Wu | 12 | 4,25 | NULL | 2026-04-02 | 2026-04-03 |
Hier bedeutet ein fehlender Rabatt, dass es keinen Rabatt gibt. Rufe zunächst die Rohfelder ab. Füge jeweils eine berechnete Spalte hinzu und verwende LIMIT 5, während du eine kleine Stichprobe prüfst.
Eine verschachtelte Berechnung verfolgen
ROUND(quantity * unit_price *
(1 - COALESCE(discount_pct, 0) / 100.0), 2)
COALESCE liefert zuerst einen bekannten Rabatt. Die Division durch 100.0 erhält dessen Nachkommateil. Die Subtraktion von 1 ergibt den bezahlten Anteil, die Multiplikation den Nettobetrag und ROUND legt die abschließende Genauigkeit fest. Der Betrag von Ana ist 33,75, der von Ben 240,0 und der von Chen 51,0. Der NULL-Rabatt von Chen wird zu null; ein fehlendes Versanddatum sollte in der Tageszahl dagegen fehlen bleiben.
Den SQLite-Bericht zusammensetzen
SELECT order_id,
first_name || ' ' || last_name AS customer,
ROUND(quantity * unit_price *
(1 - COALESCE(discount_pct, 0) / 100.0), 2) AS net_total,
strftime('%Y-%m', order_date) AS order_month,
CAST(julianday(shipped_date) - julianday(order_date)
AS INTEGER) AS days_to_ship,
CASE
WHEN shipped_date IS NULL THEN 'not shipped'
-- fast = shipped within 2 days
WHEN julianday(shipped_date) - julianday(order_date) <= 2
THEN 'fast'
ELSE 'standard'
END AS shipping
FROM orders
ORDER BY order_id;
Jeder Ausdruck hat einen klaren Ausgabealias. Die numerische Tagesdifferenz wird in INTEGER umgewandelt, weil es sich um reine Datumswerte handelt. Der IS-NULL-Zweig kommt vor dem Geschwindigkeitsvergleich, sodass eine nicht versandte Bestellung eine sinnvolle Bezeichnung erhält.
Die Ausgabe lautet:
| Bestellung | Kunde | Nettobetrag | Monat | Tage | Versand |
|---|---|---|---|---|---|
| 1001 | Ana Lopez | 33.75 | 2026-03 | 3 | standard |
| 1002 | Ben Okafor | 240.0 | 2026-03 | NULL | not shipped |
| 1003 | Chen Wu | 51.0 | 2026-04 | 1 | fast |
Typen und Abfrageklauseln anpassen
Verwende für DATE-Spalten in PostgreSQL TO_CHAR(order_date, 'YYYY-MM') für den Monat und shipped_date - order_date für die Tageszahl und den CASE-Vergleich. Behalte unit_price als exaktes numeric für ROUND mit zwei Argumenten. Die Verkettung, der Ersatzwert für den Rabatt und die Klassifizierungsregel behalten dieselbe Bedeutung.
Um in beiden Datenbanken nach gerundeten Beträgen über 50 zu filtern, wiederhole den vollständigen Nettoausdruck in WHERE. Die Bestellungen 1002 und 1003 bleiben erhalten. SQLite erlaubt auch WHERE net_total > 50, aber PostgreSQL kann diesen neuen Alias beim Filtern nicht sehen. ORDER BY net_total DESC funktioniert in beiden.
Prüfe beim Übertragen eines Berichts die Typen und Funktionsnamen in jedem Ausdruck. Eine Textfunktion muss Text erhalten, eine Datumsberechnung einen unterstützten Datumswert und ein numerischer Ersatzwert muss die gewünschte Regel ausdrücken. Setze jede Ausgabe in eine eigene Zeile; ein kurzer Kommentar kann einen geschäftlichen Schwellenwert festlegen, ohne das SQL unübersichtlich zu machen.
Wichtige Erkenntnisse
- Erstelle und prüfe jeweils eine berechnete Spalte an einer kleinen Stichprobe.
- Verschachtelte Funktionen geben ihre Ergebnisse nach außen weiter; achte auf passende Eingabetypen.
- Ein fehlender Rabatt und ein fehlendes Versanddatum können eine unterschiedliche Behandlung benötigen.
- Verwende zum Dialekt passende Datumsausdrücke und halte dabei die Berichtsregeln einheitlich.
- Filtere bei Bedarf mit dem vollständigen Ausdruck und sortiere mit seinem Ausgabealias.
Berechnete Spalten in SQL: Beispiele
1Einen Positionsbetrag mit Rabatt berechnen und prüfen
16 Schritte
- 1EinführungAus einer Zeile einen nützlichen Betrag berechnen
Eine Bestellposition erfasst acht Artikel zu je 7,50 mit 20 Prozent Rabatt. Der Bericht benötigt einen Nettobetrag, aber die Tabelle speichert nur die Eingaben. Du erstellst den Ausdruck schrittweise, benennst seine Ausgabe und prüfst, wie sich ganzzahlige Division auf den Rabatt auswirkt.
Die Beispiele verwenden SQLite und PostgreSQL. Wo sich ihre Typregeln unterscheiden, nennt das Ergebnis die Datenbank.
- 2ErklärungMit einem Ausdruck beginnen
Ein Ausdruck kombiniert Werte, um einen weiteren Wert zu erzeugen. Hier verwendet
quantity * unit_pricezwei Spalten der aktuellen Zeile.SELECT quantity * unit_price AS gross_total FROM order_lines;gross_totalist der Ausgabealias. Für die Beispielzeile ist der neue Wert in SQLite60.0. Jede andere Zeile liefert ihre eigenen Eingaben; die Abfrage schreibt diese Beträge nicht in die Tabelle zurück. - 3VerbindungJeder Zeile ist weiterhin ein Wert zugeordnet
Eine Einzelzeilenfunktion gibt für jede Eingabezeile einen Wert zurück.
ROUND(unit_price, 0)ändert den für eine Zeile angezeigten Preis, währendUPPER(item_name)ihren angezeigten Text ändert.Diese Funktionen fassen die Bestellpositionen nicht zusammen. Ein Aggregat wie SUM fasst dagegen Werte einer Gruppe zusammen und beantwortet damit eine andere Art von Frage. Eine Berechnung in SELECT kann die Details einzelner Bestellungen erhalten.
- 4TippDas Ergebnis klar benennen
AS net_totalist ein einfacher, lesbarer Alias. Verwende doppelte Anführungszeichen, wenn ein Name ein Leerzeichen enthält, wie inAS "Net Total". Einfache Anführungszeichen kennzeichnen dagegen Textwerte.Setze ein Komma zwischen Ausgabeausdrücke.
SELECT quantity unit_pricegibt eine Spalte mit Mengen unter der Überschrift unit_price zurück: Ohne Komma wird der zweite Name zum Alias. Die Abfrage kann erfolgreich sein und dabei weniger Spalten als beabsichtigt anzeigen. - 5HerausforderungDen Alias in der Abfrage einsetzen
Die Tabelle enthält nur quantity und unit_price. Eine Abfrage definiert
quantity * unit_price AS gross_total. Kann ein WHERE-Filter in PostgreSQLgross_total > 50und ORDER BYgross_total DESCverwenden?---reveal---
WHERE kann diesen neuen Alias nicht sehen, weil es logisch vor SELECT kommt. Wiederhole
quantity * unit_price > 50. ORDER BY folgt auf SELECT und kanngross_total DESCverwenden. SQLite erlaubt den Alias in WHERE als Erweiterung, PostgreSQL nicht. - 6BeispielEinen Rabatt in den bezahlten Anteil umwandeln
Der Bruttobetrag ist
8 * 7.50, also 60. Nach 20 Prozent Rabatt bleiben 80 Prozent zu zahlen. Drücke dies als1 - discount_pct / 100.0aus.quantity * unit_price * (1 - discount_pct / 100.0)Die Division ergibt
0.2; die Klammern ergeben0.8; die Multiplikation ergibt einen Nettobetrag von48.0. Die Klammern halten die Subtraktion als Faktor zusammen. - 7KernaussageEine spätere Dezimalzahl kann eine frühere Division nicht korrigieren
Angenommen, discount_pct ist eine Ganzzahl und der Divisor wird als
100geschrieben. SQLite und PostgreSQL berechnen20 / 100als ganzzahlige Division und erhalten 0. Der Faktor wird zu 1, sodass der Nettobetrag fälschlich bei 60 bleibt.Der Dezimalpreis an anderer Stelle rettet diese innere Division nicht. Verwende
100.0in der Division selbst. Die nachträgliche Umwandlung des fertigen Quotienten ändert seinen Typ, kann aber den fehlenden Nachkommateil nicht wiederherstellen. - 8HerausforderungDie Berechnung mit dem verlorenen Nachkommateil finden
Eine SQLite-Zeile hat die Ganzzahlwerte completed = 9 und assigned = 12. Was gibt
completed / assigned * 100.0zurück und wie sollte der Ausdruck stattdessen den Prozentwert berechnen?---reveal---
Er gibt
0.0zurück: Die ganzzahlige Division9 / 12wird zuerst zu 0. Schreibecompleted * 100.0 / assigned; das ergibt75.0. Die Umwandlung muss vor der Division erfolgen, nicht erst vor der abschließenden Anzeige. - 9ErklärungDie Regel für ganze Zahlen wählen
ROUND wählt einen nahe gelegenen gerundeten Wert. FLOOR geht abwärts zu einer ganzen Zahl, CEIL aufwärts und TRUNC schneidet den Nachkommateil in Richtung null ab.
Für
-6.4ergibt FLOOR den Wert-7, während CEIL und TRUNC-6ergeben. Bei negativen Eingaben ist die Richtung wichtig. PostgreSQL stellt diese Funktionen bereit; CEIL, FLOOR und TRUNC in SQLite benötigen eine mit mathematischen Funktionen kompilierte Version. ABS, das den Abstand von null liefert, ist in SQLite eingebaut. - 10TippVor dem Runden den Zahlentyp prüfen
In PostgreSQL nimmt ROUND mit zwei Argumenten
numericentgegen, nicht double precision. Schreibe für eine GleitkommaspalteROUND(CAST(amount AS numeric), 2). SQLite akzeptiert seine eigene numerische ROUND-Form.Näherungsweise gespeicherte Gleitkommawerte können bei Halbwerten überraschende Ergebnisse liefern. Für exakte Beträge speichert NUMERIC/DECIMAL in PostgreSQL exakte Dezimalzahlen; SQLite kann ganze Cent als Ganzzahlen speichern. Runde das angezeigte Ergebnis nach der Berechnung.
- 11ErklärungEine Typänderung explizit machen
CAST(expression AS type)verlangt eine Umwandlung. Der Text'28'kann mitCAST('28' AS INTEGER)zur Ganzzahl 28 werden. Die Zahl kann mitCAST(28 AS TEXT)zu Text werden.Für eine Division mit Nachkommateil benötigt SQLite REAL für einen zuverlässig nicht ganzzahligen Operanden.
CAST(7 AS NUMERIC)kann dort weiterhin die Ganzzahl 7 sein. NUMERIC in PostgreSQL liefert einen exakten Dezimaltyp. Eine Umwandlung von NULL bleibt NULL. - 12BeispielKennungen und Mengenangaben unterscheiden
Angenommen, eine Beschriftung speichert die US-Postleitzahl
'00421'. Ihre Umwandlung in eine Ganzzahl ergibt421, wobei die führenden Nullen verloren gehen. Sie ist eine Kennung, daher geht es nicht um arithmetische Berechnungen.Eine Textspalte, die tatsächlich Mengenangaben enthält, muss für eine numerische Sortierung möglicherweise umgewandelt werden. Die Textwerte
'12','3'und'80'werden in dieser Reihenfolge sortiert; die numerische Sortierung ergibt 3, 12, 80. Wähle die Umwandlung anhand der Bedeutung der Spalte. - 13HerausforderungEine Umwandlung deuten, ohne sie als Gültigkeitsprüfung zu verwenden
SQLite führt
CAST('31units' AS INTEGER)erfolgreich aus. Welchen Wert gibt die Funktion zurück und zeigt der Erfolg, dass der ursprüngliche Text eine gültige Ganzzahl war?---reveal---
Sie gibt 31 zurück, indem sie den führenden numerischen Teil liest. Der Erfolg prüft nicht die gesamte Zeichenkette auf Gültigkeit. PostgreSQL lehnt denselben Text als Ganzzahl ab. SQLite kann auch Text ohne numerischen Anfang in null umwandeln und so eine fehlerhafte Eingabe verbergen.
- 14KernaussageEine Umwandlung in eine Ganzzahl funktioniert nicht überall gleich
Für den numerischen Wert
4.7schneidetCAST(... AS INTEGER)in SQLite auf 4 ab, während PostgreSQL auf 5 rundet. Wenn ein Bericht „ganze Einheiten, die diesen Wert nicht überschreiten“ meint, drücke dies vor der Umwandlung mit FLOOR aus.Auch eine implizite Typumwandlung hängt von der Datenbank ab. PostgreSQL kann bei arithmetischen Ausdrücken aus einem Literal in Anführungszeichen eine Zahl ableiten, aber eine TEXT-Spalte braucht eine explizite Umwandlung. Die sichtbaren Zeichen allein legen den Typ des Operanden nicht fest.
- 15HerausforderungDen vollständigen Nettoausdruck prüfen
Für acht Artikel zu je 7,50 mit ganzzahligem discount_pct = 20 schreibt ein Bericht
ROUND(quantity * unit_price * (1 - discount_pct / 100.0), 2) AS net_total. Was ist das Ergebnis und kann dieser Alias die Ausgabe sortieren?---reveal---
Der Bruttobetrag ist 60, der bezahlte Anteil 0,8 und der Nettobetrag in SQLite
48.0.ORDER BY net_totalist sowohl in SQLite als auch in PostgreSQL gültig, weil die Sortierung den SELECT-Alias sehen kann. - 16ZusammenfassungEingaben, Berechnung und Ausgabenamen lesen
Ein berechneter Betrag entsteht in mehreren Schritten: Die Zeile liefert Werte, arithmetische Ausdrücke und Funktionen erzeugen das Ergebnis und ein Alias benennt es. Prüfe die Reihenfolge der Operationen und die Typen der Operanden, bevor du eine angezeigte Zahl übernimmst.
Ist ein Ergebnis unerwartet, untersuche zuerst eine innere Division oder Typumwandlung. Um einen berechneten Wert datenbankübergreifend zu filtern, wiederhole seinen Ausdruck in WHERE; zum Sortieren verwende den Ausgabealias in ORDER BY.
2Fehlende Daten durch eine Abfrage verfolgen
12 Schritte
Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.
- 1EinführungEin fehlender Betrag ändert mehr als eine Zelle
- 2ErklärungNULL ist eine unbekannte Eingabe
- 3BeispielEine Prüfung auf fehlende Werte verwenden
- 4KernaussageWHERE akzeptiert nur TRUE
- 5HerausforderungEine bekannte mit einer unbekannten Bedingung kombinieren
- 6TippNULL nicht in einer Ausschlussliste belassen
- 7ErklärungEinen Ersatzwert nach der Bedeutung wählen
- 8BeispielDen Anzeigetyp einheitlich halten
- 9BeispielEinen Nenner von null in eine Lücke umwandeln
- 10HerausforderungLeeren Text vor der Bezeichnung bereinigen
- 11HerausforderungEine Anzeigeentscheidung von einer Filterentscheidung trennen
- 12ZusammenfassungDie Bedeutung einer Lücke sichtbar halten
3Einen Namen bereinigen und eine E-Mail-Domain extrahieren
14 Schritte
Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.
- 1EinführungText nutzbar machen, ohne seine Teile zu verlieren
- 2BeispielDas Leerzeichen zwischen Namen einfügen
- 3ErklärungEntscheiden, was ein fehlender Namensteil bewirkt
- 4BeispielDie E-Mail-Adresse von innen nach außen bereinigen
- 5HerausforderungZwischen dem Entfernen an Rändern und dem Ersetzen wählen
- 6TippZeichen- und Dialektregeln prüfen
- 7ErklärungAb eins zählen
- 8BeispielDas Trennzeichen finden
- 9BeispielDie Zeichen vor und nach @ entnehmen
- 10HerausforderungDas um eine Position verschobene Ergebnis finden
- 11KernaussageEin Suchergebnis von null braucht einen eigenen Weg
- 12TippEnden entnehmen und Codes im richtigen Dialekt auffüllen
- 13HerausforderungBereinigung und Extraktion kombinieren
- 14ZusammenfassungDie genauen Zeichen verfolgen
4Datumsbezeichnungen und zuverlässige Zeitraumfilter erstellen
18 Schritte
Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.
- 1EinführungDen Kalenderwert von seiner Bezeichnung trennen
- 2ErklärungEine eindeutige Datumsdarstellung wählen
- 3BeispielEin festes lokales Format einlesen
- 4HerausforderungErklären, welcher Text nach Datum sortiert wird
- 5TippDas Einlesen und die aktuelle Zeitbasis prüfen
- 6BeispielDen Monat mit dem richtigen Rückgabetyp extrahieren
- 7ErklärungDas Jahr in der Monatsbezeichnung behalten
- 8BeispielEine Anzeige erstellen, ohne die Sortierung zu ändern
- 9HerausforderungDas richtige Quartal finden
- 10VerbindungDie Nummerierungskonvention für Wochentage wählen
- 11BeispielZehn Tage zur Buchung addieren
- 12KernaussageEin Monat ist keine feste Anzahl von Tagen
- 13BeispielTage und Stunden in passenden Einheiten messen
- 14HerausforderungDen letzten Nachmittag des Monats einschließen
- 15ErklärungGeburtstage zählen, die tatsächlich erreicht wurden
- 16TippRelative Datumswerte als veränderliche Grenzen lesen
- 17HerausforderungEine Frist mit einer Monatsauswahl kombinieren
- 18ZusammenfassungTyp, Kalenderregel und Bereichsgrenzen prüfen
5Bestellungen bezeichnen und den abschließenden Bericht erstellen
17 Schritte
Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.
- 1EinführungJeder Bestellung eine nützliche Bezeichnung geben
- 2ErklärungDie erste wahre Bedingung wählen
- 3BeispielDen exakten Grenzwert verfolgen
- 4KernaussageELSE kann auch einen unbekannten Betrag erfassen
- 5HerausforderungEinen verdeckten kleinen Bereich reparieren
- 6TippKompatible Ergebnisse zurückgeben
- 7BeispielEinen Statuswert übersetzen
- 8HerausforderungWarum erfasst WHEN NULL die Zeile nicht?
- 9BeispielPriorität nach Rang sortieren
- 10KernaussageEin Flag kann bekannte und unbekannte Fälle zusammenfassen
- 11BeispielDen Bericht mit bekannten Eingaben beginnen
- 12BeispielZuerst den Nettobetrag berechnen
- 13BeispielDatumswerte mit einer eigenen Regel für fehlende Werte hinzufügen
- 14HerausforderungEine zweite Zeile anhand beider Regeln prüfen
- 15VerbindungDie Datumsausdrücke für PostgreSQL übersetzen
- 16HerausforderungDen Betrag filtern, den der Bericht tatsächlich zeigt
- 17ZusammenfassungDen Bericht als Folge ausdrücklicher Entscheidungen prüfen
Berechnete Spalten in SQL: Übungsaufgaben
Set 1: Beträge berechnen und fehlende Daten behandeln10 Übungsfragen
Frage 1 von 10
units und unit_cost. Welche SELECT-Liste gibt ihr Produkt unter der Überschrift extended_cost zurück?Antwort zeigenAntwort ausblenden
units * unit_cost multipliziert die Werte jeder Zeile und AS extended_cost benennt diese Ausgabe. Ein Komma vor dem Namen fordert eine separate Spalte an, die diese Tabelle nicht hat. Einfache Anführungszeichen würden unit_cost zu einem Textliteral statt zu einem Verweis auf die Kostenspalte machen.Frage 2 von 10
lines enthält nur units und price. Eine Abfrage muss in SQLite und PostgreSQL laufen. Wie soll sie Zeilen mit einem Produkt über 90 behalten und das größte Produkt zuerst sortieren?Antwort zeigenAntwort ausblenden
units * price in WHERE, weil PostgreSQL einen neuen SELECT-Alias in diesem Schritt nicht verwenden kann. ORDER BY kommt logisch nach SELECT und kann den Alias daher mit DESC sortieren. SQLite akzeptiert den Alias möglicherweise in WHERE, aber diese Version würde die Anforderung nicht erfüllen, in beiden Datenbanken zu laufen.Frage 3 von 10
SELECT 14 + 5 * 3; in SQLite zurück?Antwort zeigenAntwort ausblenden
5 * 3 als 15 und addiert dann 14 zum Ergebnis 29. Das Ergebnis 57 entsteht, wenn zuerst 14 und 5 addiert werden. Diese Reihenfolge würde Klammern um 14 + 5 benötigen; der gezeigte Ausdruck hat keine.Frage 4 von 10
old_count und new_count Ganzzahlen mit den Werten 60 und 69. Was ist das Ergebnis von (new_count - old_count) / old_count * 100?Antwort zeigenAntwort ausblenden
9 / 60 ist eine ganzzahlige Division, die vor der Multiplikation mit 100 den Wert 0 erzeugt. Der beabsichtigte Prozentwert ist 15, aber der Ausdruck verliert zuerst seinen Nachkommateil. Mit (new_count - old_count) * 100.0 / old_count bleibt die benötigte Dezimalrechnung erhalten.Frage 5 von 10
units = 5 und discount_pct = 12 sowie price = 18.0. Welches Ergebnis erzeugt ROUND(units * price * (1 - discount_pct / 100), 2)?Antwort zeigenAntwort ausblenden
12 / 100 verwendet zwei Ganzzahlen, daher schneidet SQLite das Ergebnis auf 0 ab. Der Faktor wird zu 1 und ROUND erhält den vollen Betrag 5 * 18.0, was 90,0 ergibt. Der Betrag mit Rabatt von 79,2 benötigt einen Dezimaloperanden innerhalb dieser Division; anschließendes Runden kann den verlorenen Nachkommateil nicht wiederherstellen.Frage 6 von 10
CAST('27boxes' AS INTEGER) zurück?Antwort zeigenAntwort ausblenden
Frage 7 von 10
delivery_date?Antwort zeigenAntwort ausblenden
IS NULL prüft direkt, ob ein Wert fehlt, und gibt eindeutig TRUE oder FALSE zurück. Ein Gleichheitsvergleich mit NULL ergibt selbst bei einem fehlenden Lieferdatum UNKNOWN, sodass WHERE keine solchen Zeilen behalten würde. Leerer Text ist in SQLite und PostgreSQL eine erfasste Zeichenkette und keine Markierung für ein unbekanntes Datum.Frage 8 von 10
region-Werte: 'East', 'West', NULL und 'North'. Wie viele Zeilen erfüllen WHERE NOT (region = 'East')?Antwort zeigenAntwort ausblenden
Frage 9 von 10
'unlisted' angezeigt werden. Welcher Ausdruck erreicht dies und erhält erfasste Nummern?Antwort zeigenAntwort ausblenden
COALESCE(phone, '', 'unlisted') lässt leeren Text unverändert und wählt ihn sogar als Ersatzwert, bevor die Bezeichnung erreicht wird.Frage 10 von 10
sales und visits. Eine Rate soll Prozentwerte mit Nachkommateil erhalten und NULL bleiben, wenn visits null ist. Sie darf keine Rate von null erfinden. Welcher Ausdruck passt?Antwort zeigenAntwort ausblenden
Set 2: Text bereinigen und mit Kalenderwerten arbeiten10 Übungsfragen
Speichere diese Einheit, um jede Antwort zu sehen und jedes Set zu üben.
Frage 1 von 10
LOWER(TRIM(' RAE@Mail.COM ')) in SQLite zurück?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 2 von 10
first_name = 'Mira', middle_name = NULL und last_name = 'Shah'. Was geben first_name || ' ' || middle_name || ' ' || last_name und CONCAT_WS(' ', first_name, middle_name, last_name) in dieser Reihenfolge zurück?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 3 von 10
SUBSTR('Seattle', 3, 3) in SQLite zurück?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 4 von 10
email NULL oder Text ohne @ enthalten. Gib bei Text mit @ alles nach dem ersten @ zurück, andernfalls NULL. Welcher Ausdruck passt?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 5 von 10
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 6 von 10
date('2027-04-31') zurück?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 7 von 10
d den Wert '2027-08-19'. Wie lauten die Ergebnisse von strftime('%m', d) = 8 und CAST(strftime('%m', d) AS INTEGER) = 8 in dieser Reihenfolge?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 8 von 10
event_date umfasst mehrere Jahre. Ein Bericht zeigt Datumswerte als MM/DD/YYYY an und muss die zeitliche Reihenfolge erhalten. Wie soll er die Spalte auswählen und sortieren?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 9 von 10
d ist '2027-04-24'. Was gibt date(d, '+10 days') zurück?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 10 von 10
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Set 3: Zeilen klassifizieren und Berichtslogik untersuchen10 Übungsfragen
Speichere diese Einheit, um jede Antwort zu sehen und jedes Set zu üben.
Frage 1 von 10
score = 75: CASE WHEN score < 60 THEN 'review' WHEN score < 80 THEN 'ready' ELSE 'strong' END?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 2 von 10
CASE WHEN amount < 500 THEN 'regular' WHEN amount < 100 THEN 'small' ELSE 'large' END für Beträge, die nicht NULL sind, niemals 'small' zurück?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 3 von 10
balance kann NULL sein. Gefordert sind die Bezeichnungen 'unknown' für fehlende Werte, 'credit' unter 0, 'settled' bei 0 und 'due' über 0. Welcher CASE-Ausdruck erfüllt alle Regeln?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 4 von 10
state-Wert 'H' bedeutet zurückgehalten und 'R' bedeutet freigegeben. Was gibt CASE state WHEN 'H' THEN 'held' WHEN 'R' THEN 'released' ELSE 'other' END für 'R' zurück?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 5 von 10
'urgent', 'normal' und 'deferred' in dieser Reihenfolge sortieren, alle anderen Prioritäten und NULL zuletzt. Welcher ORDER-BY-Ausdruck passt?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 6 von 10
qty = 4, price = 15.0, discount_pct = NULL und shipped_date = NULL. Ein fehlender Rabatt bedeutet, dass es keinen gibt. Welches Wertepaar ergibt sich aus ROUND(qty * price * (1 - COALESCE(discount_pct, 0) / 100.0), 2) und CASE WHEN shipped_date IS NULL THEN 'open' ELSE 'sent' END?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 7 von 10
LOWER(TRIM(customer)) AS name und date(due_date, '+7 days') AS reminder_date. Der Rohwert von customer ist ' IVAN ' und due_date ist '2027-09-26'. Welches Ausgabepaar sollte eine Stichprobenprüfung ergeben?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 8 von 10
x-Werte 2, 7, NULL und 11. Wie viele Zeilen ergeben WHERE x NOT IN (2, NULL) beziehungsweise WHERE x <> 2 OR x IS NULL?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 9 von 10
'1998-12-18' geboren. Wie alt ist sie am '2027-12-17' in vollendeten Jahren und warum kann die Subtraktion der beiden Jahreszahlen falsch sein?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 10 von 10
rating kann NULL sein. Eine Anzeigespalte muss die Bewertung als Text oder 'unrated' zeigen. Welcher Ausdruck passt?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Set 4: Vollständige Berichte und knifflige Grenzen prüfen10 Übungsfragen
Speichere diese Einheit, um jede Antwort zu sehen und jedes Set zu üben.
Frage 1 von 10
qty, price vom Typ NUMERIC und ganzzahliges discount_pct. Ein fehlender Rabatt bedeutet, dass es keinen gibt. Ein Bericht muss gerundete Nettobeträge über 75 behalten und absteigend sortieren. Welche vollständige Abfrage passt?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 2 von 10
reading hat den Typ DOUBLE PRECISION. Wie kann ein Bericht sie auf zwei Dezimalstellen runden, ohne einen Fehler bei der Funktionssignatur auszulösen?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 3 von 10
COALESCE(NULL, '', 'backup') in SQLite zurück?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 4 von 10
email = 'nora@research.org'. Welches Ergebnis erzeugt SUBSTR(email, INSTR(email, '@'))?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 5 von 10
'2027-01-31' in SQLite ab 3.46 date(d, '+1 month'), in SQLite date(d, '+1 month', 'floor') und in PostgreSQL DATE '2027-01-31' + INTERVAL '1 month'. Welche Kalenderdaten ergeben sich in dieser Reihenfolge?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 6 von 10
stock kann NULL sein. Gefordert ist ein numerisches Flag: NULL für unbekannten Bestand, 1 für Bestand unter 5 und sonst 0. Welcher Ausdruck passt?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 7 von 10
'2027-05-08 10:15:00' bis '2027-05-08 13:45:00'. Was gibt (unixepoch(end_time) - unixepoch(start_time)) / 3600.0 zurück?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 8 von 10
qty = 6, price = 8.0, discount_pct = 25, wurde am '2027-07-10' bestellt und am '2027-07-12' versandt. Der Nettobetrag verwendet ROUND(qty * price * (1 - COALESCE(discount_pct, 0) / 100.0), 2). Ein CASE-Ausdruck bezeichnet NULL beim Versand als 'open', vergangene Tage <= 2 als 'fast' und sonst als 'standard'. Welcher Nettobetrag und welche Bezeichnung ergeben sich?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 9 von 10
d. Wie kann er das Quartal für jeden Monat berechnen?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 10 von 10
(qty 3, price 22.0, discount_pct NULL), B (qty 4, price 20.0, discount_pct 25) und C (qty 2, price 40.0, discount_pct 10). Ein fehlender Rabatt bedeutet, dass es keinen gibt. Die Abfrage berechnet ROUND(qty * price * (1 - COALESCE(discount_pct, 0) / 100.0), 2) AS net, behält net > 60 mit dem vollständigen Ausdruck in WHERE und sortiert nach net DESC. Wie lautet die Reihenfolge der Zeilen?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Hängst du bei deiner eigenen Aufgabe fest? Hausaufgabenhilfe
Schlüsselbegriffe
A
Auffüllen (Padding)
LPAD('42', 5, '0') in PostgreSQL gibt '00042' zurück und macht einen kurzen Code fünf Zeichen lang.Ausdruck
quantity * unit_price ein Ausdruck, der für jede Zeile den Positionsbetrag erzeugt.B
benutzerdefinierter Sortierrang
berechnete Spalte
quantity * unit_price AS line_total anzeigen, selbst wenn die Tabelle keine Spalte line_total hat.Berichtsabfrage
C
CASE-Suchausdruck
CASE WHEN total < 50 THEN 'small' ELSE 'large' END wählt eine Bezeichnung anhand des Betrags der Zeile.CEIL
CEIL(4.1) ergibt 5, weil vier unter der Eingabe liegt und fünf die nächste ganze Zahl ist.COALESCE
COALESCE(mobile_phone, home_phone, 'no phone') verwendet die Festnetznummer, wenn die Mobilnummer fehlt.D
DATE
DATE '2026-03-14' kennzeichnet den 14. März 2026 ausdrücklich als PostgreSQL-Datumswert.Datentyp
'42' und die Ganzzahl 42 können in einer Tabelle gleich aussehen, sich in SQL aber unterschiedlich verhalten.dreiwertige Logik
FALSE AND UNKNOWN ist FALSE, aber TRUE AND UNKNOWN bleibt UNKNOWN, weil die zweite Bedingung ungeklärt ist.E
einfacher CASE-Ausdruck
CASE status WHEN 'S' THEN 'Shipped' ELSE 'Other' END übersetzt einen gespeicherten Statuscode.Einzelzeilenfunktion
UPPER(city) in SELECT ändert den angezeigten Stadttext für jeden Kunden, den die Abfrage zurückgibt.ELSE-Zweig
ELSE 'large' erreichen, sofern nicht ein früherer Zweig ausdrücklich total IS NULL prüft.Ersatzwert
explizite Typumwandlung
CAST(quantity AS REAL) / 4 ändert den SQLite-Operanden, bevor die Division einen Nachkommateil verlieren kann.EXTRACT
EXTRACT(MONTH FROM DATE '2026-03-14') in PostgreSQL gibt den numerischen Monatswert 3 zurück.F
FLOOR
FLOOR(-4.1) gleich -5 und unterscheidet sich damit vom bloßen Abschneiden des Nachkommateils.Formatmuster
'%m/%d/%Y' für eine Datumsbezeichnung im US-Format; TO_CHAR in PostgreSQL verwendet 'MM/DD/YYYY'.G
ganzzahlige Division
7 / 2 ergibt 3; wird der zweite Operand zu 2.0 gemacht, bleibt der Nachkommateil erhalten und das Ergebnis ist 3,5.Gleitkommazahl
0.1 + 0.2 = 0.3 falsch sein, weil die gespeicherten Näherungswerte nicht denselben Wert ergeben.Grenzwert
total < 50 falsch; wird die Prüfung in total <= 50 geändert, ist sie wahr.H
halboffener Bereich
ordered_at >= '2026-03-01' AND ordered_at < '2026-04-01' schließt alle Zeitstempel im März ein.I
implizite Typumwandlung
'Order #' || 42 die 42 in Text um und erzeugen die Bezeichnung 'Order #42'.INSTR
INSTR('ana@example.com', '@') ergibt 4, während eine Zeichenkette ohne @ null ergibt.Intervall
INTERVAL '1 month' zu einem DATE in PostgreSQL gibt einen Zeitstempel zurück und folgt dessen Monatsendregel.IS NULL
WHERE phone IS NULL ruft Kunden ohne erfasste Telefonnummer ab, ohne einen Wert durch Gleichheit mit NULL zu vergleichen.ISO-Datumsformat
'2026-03-14' enthält führende Nullen und wird in Datumsreihenfolge vor '2026-11-02' sortiert.J
julianische Tageszahl
julianday(end_date) - julianday(start_date), statt ISO-Datumszeichenketten direkt zu subtrahieren.L
LENGTH
LENGTH(' Bo ') ergibt 4, weil beide Leerzeichen an den Rändern ebenso wie die beiden Buchstaben zählen.Literal
first_name || ' ' || last_name ist ein von der Abfrage geliefertes Textliteral.logische Verarbeitungsreihenfolge
M
Modulo
135 % 60 die 15 Minuten, die nach zwei vollständigen Stunden verbleiben.Monatsbezeichnung
'2026-03' hält in einer Berichtsanzeige März 2026 von März 2025 getrennt.N
NULL
salary + bonus unbekannt, obwohl das Gehalt des Mitarbeiters erfasst ist.NULL-sicherer Vergleich
NULL IS NOT DISTINCT FROM NULL ist in PostgreSQL und in SQLite ab Version 3.39 TRUE.NULLIF
NULLIF(visits, 0) behält positive Besucherzahlen, wandelt aber null für eine Rate in einen fehlenden Divisor um.numerische Zeichenkette
'10', '100' und '9' erscheinen in dieser aufsteigenden Textreihenfolge, die sich von der numerischen Reihenfolge unterscheidet.numerisches Flag
CASE WHEN discount_pct > 0 THEN 1 ELSE 0 END weist sowohl fehlenden als auch nicht positiven Rabatten null zu.O
Operatorrangfolge
10 + 3 * 2 vor der Addition, sodass das Ergebnis 16 statt 26 ist.P
Platzhalterwert
NULLIF(phone, '') wandelt eine leere Telefonzeichenkette in NULL um, bevor eine Anzeigebezeichnung eingesetzt wird.R
REPLACE
REPLACE('555-0100', '-', '') entfernt den Bindestrich und zeigt '5550100' an, ohne die Tabelle zu ändern.ROUND
ROUND((price - cost) / price * 100, 1), um eine Marge mit einer Dezimalstelle anzuzeigen.S
Sortierfolge (Collation)
'Boston' = 'boston' wahr machen, während dies mit den Standardeinstellungen von SQLite nicht gilt.Spaltenalias
AS line_total und kann ihn mit ORDER BY line_total sortieren.Stichprobenprüfung
LIMIT 5 beim Erstellen des Berichts erleichtert es, ein fehlendes Leerzeichen oder einen Fehler durch ganzzahlige Division zu finden.strftime
strftime('%m', '2026-03-14') gibt '03' zurück. Vergleiche das Ergebnis mit Text oder wandle es vor einer numerischen Verwendung um.T
Teilzeichenkette
SUBSTR('Boston', 1, 3) gibt 'Bos' zurück und nimmt dabei drei Zeichen ab der ersten Position.TIMESTAMP
'2026-03-31 14:05:00' liegt nach Mitternacht zu Beginn des 31. März.TRIM
TRIM(' New York ') bleiben die beiden Leerzeichen zwischen den Wörtern im zurückgegebenen Text erhalten.Typaffinität
U
Umwandlung der Groß- und Kleinschreibung
LOWER(TRIM(email)) vereinheitlicht eine bereinigte ASCII-E-Mail-Adresse für einen Vergleich mit angeglichener Groß- und Kleinschreibung.Unixzeit
3600.0, um Stunden mit Nachkommateil in einer Dauer zu erhalten.UNKNOWN
bonus = NULL ist UNKNOWN und kann daher einen fehlenden Bonus in einem WHERE-Filter nicht finden.UTC
V
Verkettung
first_name || ' ' || last_name fügt ein Leerzeichen zwischen die beiden erfassten Namensteile ein.Verschachtelung von Funktionen
ROUND(COALESCE(amount, 0), 2) wird der Ersatzwert bestimmt, bevor die Rundungsfunktion ihre Eingabe erhält.vollendetes Lebensalter
W
WHEN-Zweig
< 200 an erster Stelle kann verhindern, dass ein späterer Zweig mit < 50 jemals ausgewählt wird.Z
Zeichenkette
' New York ' enthält Leerzeichen an den Rändern und zwei innere Leerzeichen, die ihre Länge beeinflussen.Zeichenposition
'ana@example.com' steht an Position 4, die Domain beginnt daher an Position 5.- 1Relationale Datenbanken
- 2Abfragen mit SELECT
- 3Berechnete Spalten in SQL
- 4SQL-Aggregation
- 5SQL-Joins
- 6Datenbanktabellen erstellen und ändern
Über diese Einheit
Erstelle deine eigenen Lernmaterialien
Mach aus deinen Notizen, Folien und Dokumenten Lernleitfäden, Übungsfragen, Karteikarten und 6 weitere Tools.