Alle BeiträgeDas PerSight-Team · Zuletzt aktualisiert: 25. Juli 2026 · 8 Min. Lesezeit

SQL-Datumsfunktionen im Vergleich: PostgreSQL, SQL Server, MySQL und Oracle

Heutiges Datum, 30 Tage zurück, auf Monatsanfang runden, Jahr und Monat extrahieren, Datumsdifferenz und Formatierung: die 6 meistgebrauchten Datumsoperationen, nebeneinander in allen vier Dialekten.

Bei Datumsfunktionen driften die SQL-Dialekte am weitesten auseinander. Eine für PostgreSQL geschriebene Abfrage bricht auf Oracle, und was auf SQL Server läuft, liefert auf MySQL etwas anderes. Diese Seite ist eine Referenz, die die sechs meistgebrauchten Operationen in der Syntax aller vier Engines nebeneinanderstellt; sie wurde zum Bookmarken geschrieben.

1. Heutiges Datum und aktuelle Zeit

-- PostgreSQL
SELECT CURRENT_DATE, NOW();

-- SQL Server
SELECT CAST(GETDATE() AS date), GETDATE();

-- MySQL
SELECT CURDATE(), NOW();

-- Oracle
SELECT TRUNC(SYSDATE), SYSDATE FROM dual;
Oracle verlangt FROM dual; TRUNC(SYSDATE) nullt den Zeitanteil und liefert "heute".

2. Tage oder Monate addieren und subtrahieren

-- PostgreSQL
SELECT CURRENT_DATE - INTERVAL '30 days';
SELECT CURRENT_DATE + INTERVAL '3 months';

-- SQL Server
SELECT DATEADD(DAY, -30, CAST(GETDATE() AS date));
SELECT DATEADD(MONTH, 3, CAST(GETDATE() AS date));

-- MySQL
SELECT DATE_SUB(CURDATE(), INTERVAL 30 DAY);
SELECT DATE_ADD(CURDATE(), INTERVAL 3 MONTH);

-- Oracle
SELECT TRUNC(SYSDATE) - 30 FROM dual;
SELECT ADD_MONTHS(TRUNC(SYSDATE), 3) FROM dual;
In Oracle ist Tage-Addieren simple Arithmetik (Datum + Zahl); für Monate braucht es ADD_MONTHS.

3. Auf Monats- oder Jahresanfang runden

Das ist die Grundlage aller Filter vom Typ "seit Monatsanfang", und die vier Engines gehen vier verschiedene Wege:

-- PostgreSQL
SELECT date_trunc('month', CURRENT_DATE);

-- SQL Server (2022+)
SELECT DATETRUNC(month, GETDATE());
-- SQL Server (ältere Versionen)
SELECT DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), 1);

-- MySQL (kein eingebautes Trunc; Erster-Tag-Muster)
SELECT DATE_FORMAT(CURDATE(), '%Y-%m-01');

-- Oracle
SELECT TRUNC(SYSDATE, 'MM') FROM dual;
Für Jahresanfang: date_trunc('year',...), DATETRUNC(year,...), '%Y-01-01', TRUNC(SYSDATE, 'YYYY').

4. Jahr, Monat und Tag extrahieren

-- PostgreSQL / Oracle (Standard)
SELECT EXTRACT(YEAR FROM bestelldatum),
       EXTRACT(MONTH FROM bestelldatum)
FROM bestellungen;

-- SQL Server
SELECT YEAR(bestelldatum), MONTH(bestelldatum), DAY(bestelldatum)
FROM bestellungen;

-- MySQL (beides funktioniert)
SELECT YEAR(bestelldatum), EXTRACT(MONTH FROM bestelldatum)
FROM bestellungen;

5. Die Differenz zweier Daten

-- PostgreSQL (Datum - Datum = Anzahl Tage)
SELECT lieferdatum - bestelldatum AS tage FROM bestellungen;

-- SQL Server (Achtung: erst die Einheit, dann das frühere Datum)
SELECT DATEDIFF(DAY, bestelldatum, lieferdatum) FROM bestellungen;

-- MySQL (Achtung: UMGEKEHRTE Reihenfolge zu SQL Server, keine Einheit)
SELECT DATEDIFF(lieferdatum, bestelldatum) FROM bestellungen;

-- Oracle (Datum - Datum = Tage, ggf. mit Nachkommastellen)
SELECT lieferdatum - bestelldatum FROM bestellungen;
Die klassische Falle: DATEDIFF gibt es in beiden Engines, mit vertauschter Argumentreihenfolge. MySQL will das spätere Datum zuerst.

6. Ein Datum als Text formatieren

-- PostgreSQL / Oracle
SELECT TO_CHAR(bestelldatum, 'YYYY-MM') FROM bestellungen;

-- SQL Server
SELECT FORMAT(bestelldatum, 'yyyy-MM') FROM bestellungen;

-- MySQL
SELECT DATE_FORMAT(bestelldatum, '%Y-%m') FROM bestellungen;
Der Standard-Gruppierschlüssel für monatliche GROUP-BY-Berichte: der Jahr-Monat-String.

Eine Schlussnotiz: Wenn Sie diese Muster mit Datumsbereichsfiltern kombinieren, denken Sie an die Regel des halboffenen Intervalls (Anfang inklusive, Ende exklusive); Details in unserem Leitfaden zum Datumsfiltern. Zeitzonen sind ein eigenes Thema: Speichert die Spalte UTC, landen Mitternachtsdatensätze am falschen Tag, sofern Sie "heute" nicht in derselben Zone berechnen.

Häufig gestellte Fragen

Was unterscheidet GETDATE von SYSDATETIME?
Beide liefern in SQL Server die aktuelle Zeit; GETDATE gibt datetime (3 ms Präzision), SYSDATETIME datetime2 (100 ns) zurück. In neuem Code ist SYSDATETIME vorzuziehen, fürs Reporting tun es beide.
Warum hat MySQL kein date_trunc?
MySQL hat die Funktion nie eingebaut; die Community nutzt das Erster-Tag-Muster mit DATE_FORMAT. Neuere MariaDB-Versionen haben ähnliche Funktionen, aber für Portabilität bleiben Sie beim Muster.
Wie schreibt man ein Datumsliteral in Oracle?
Am sichersten die ANSI-Form: DATE '2026-01-01'. TO_DATE('01/01/2026','DD/MM/YYYY') geht auch, aber meiden Sie Formate, die von Sitzungseinstellungen abhängen.
Muss ich mir diese Unterschiede merken?
Müssen Sie nicht; genau dafür gibt es diese Seite. Einen Schritt weiter geht, den Dialekt gar nicht mehr zu denken: Tippen Sie Ihre Frage in PerSight in natürlicher Sprache, und es wählt die Datumsfunktionen passend zur verbundenen Engine und zeigt Ihnen das erzeugte SQL.

Quellen