SQL Date Functions Compared: PostgreSQL, SQL Server, MySQL, and Oracle
Today's date, going back 30 days, truncating to month, extracting year and month, date differences, and formatting: the 6 most-needed date operations, side by side in all four database dialects.
Date functions are where SQL dialects diverge the most. A query written for PostgreSQL breaks on Oracle, and one that works on SQL Server returns something else on MySQL. This page is a reference that puts the six most-needed operations side by side in all four engines' own syntax; it was written to be bookmarked.
1. Today's date and the current time
-- PostgreSQL
SELECT CURRENT_DATE, NOW();
-- SQL Server
SELECT CAST(GETDATE() AS date), GETDATE();
-- MySQL
SELECT CURDATE(), NOW();
-- Oracle
SELECT TRUNC(SYSDATE), SYSDATE FROM dual;2. Adding and subtracting days or months
-- 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;3. Truncating to the start of month or year
This is the foundation of "since the start of this month" filters, and the four engines take four different roads:
-- PostgreSQL
SELECT date_trunc('month', CURRENT_DATE);
-- SQL Server (2022+)
SELECT DATETRUNC(month, GETDATE());
-- SQL Server (older versions)
SELECT DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), 1);
-- MySQL (no built-in trunc; first-day pattern)
SELECT DATE_FORMAT(CURDATE(), '%Y-%m-01');
-- Oracle
SELECT TRUNC(SYSDATE, 'MM') FROM dual;4. Extracting year, month, and day
-- PostgreSQL / Oracle (standard)
SELECT EXTRACT(YEAR FROM order_date),
EXTRACT(MONTH FROM order_date)
FROM orders;
-- SQL Server
SELECT YEAR(order_date), MONTH(order_date), DAY(order_date)
FROM orders;
-- MySQL (both work)
SELECT YEAR(order_date), EXTRACT(MONTH FROM order_date)
FROM orders;5. The difference between two dates
-- PostgreSQL (date - date = number of days)
SELECT delivery_date - order_date AS days_between FROM orders;
-- SQL Server (careful: unit first, then the earlier date)
SELECT DATEDIFF(DAY, order_date, delivery_date) FROM orders;
-- MySQL (careful: REVERSED order vs SQL Server, no unit)
SELECT DATEDIFF(delivery_date, order_date) FROM orders;
-- Oracle (date - date = days, possibly fractional)
SELECT delivery_date - order_date FROM orders;6. Formatting a date as text
-- PostgreSQL / Oracle
SELECT TO_CHAR(order_date, 'YYYY-MM') FROM orders;
-- SQL Server
SELECT FORMAT(order_date, 'yyyy-MM') FROM orders;
-- MySQL
SELECT DATE_FORMAT(order_date, '%Y-%m') FROM orders;One closing note: when combining these with date range filters, remember the half-open interval rule (start inclusive, end exclusive); details in our date filtering guide. Time zones are their own trouble: if the column stores UTC, midnight records land on the wrong day unless you compute "today" in the same zone.
Frequently asked questions
- What is the difference between GETDATE and SYSDATETIME?
- Both return the current time in SQL Server; GETDATE returns datetime (3 ms precision), SYSDATETIME returns datetime2 (100 ns). Prefer SYSDATETIME in new code, though either works for reporting.
- Why does MySQL have no date_trunc?
- MySQL never added it; the community uses the DATE_FORMAT first-day pattern. Recent MariaDB versions have similar functions, but stick to the pattern if you want portability.
- How do I write a date literal in Oracle?
- The safest is the ANSI form: DATE '2026-01-01'. TO_DATE('01/01/2026','DD/MM/YYYY') works too, but avoid formats that depend on session settings.
- Do I have to memorize these differences?
- You do not; that is exactly why this page exists. One step further is not thinking about the dialect at all: type your question into PerSight in plain language, and it picks the date functions matching whichever engine you are connected to, showing you the SQL it generated.
References
Related articles
- Filtering by Date Range in SQL (Including the BETWEEN Trap)This month, the last 30 days, last quarter: the safe way to query a date range in SQL. Why BETWEEN misleads once times are involved, and the PostgreSQL, SQL Server, MySQL, and Oracle equivalents.
- SQL GROUP BY: Making Sense of Grouping and AggregationMonthly revenue, orders per customer, units by category: aggregation with GROUP BY. COUNT/SUM/AVG, the difference between WHERE and HAVING, and MySQL's ONLY_FULL_GROUP_BY trap, with real examples.
- What Is Text-to-SQL? Natural Language to SQL, Explained PlainlyText-to-SQL (NL2SQL) is the AI technique that turns a natural-language question into a runnable SQL query. How it works, where it fails, and what safe usage requires. A guide without the marketing.