الانتقال إلى المحتوى الرئيسي
eLearner.app
الوحدة 6 · الدرس 2 من 422/57 في الدورة~12 min
دروس الوحدة (2/4)

وظائف التاريخ والطابع الزمني

Dates and timestamps are everywhere: orders, logins, events, billing. In this lesson we see how to extract parts from a date (year, month…), truncate it to a granularity (month, week…), compute intervals and differences, and make comparisons across periods.

The base types

PostgreSQL distinguishes:

  • DATE — date only, format YYYY-MM-DD;
  • TIMESTAMP — date + time, no timezone;
  • TIMESTAMPTZ — date + time + timezone;
  • INTERVAL — a period (e.g. '3 days', '2 hours 30 minutes').

In our ecommerce dataset:

ColumnType
customers.signed_up_onDATE
orders.ordered_atTIMESTAMP
orders.shipped_atTIMESTAMP (can be NULL)

EXTRACT — reading a part

EXTRACT(part FROM date) extracts a number:

SQL
SELECT EXTRACT(YEAR  FROM ordered_at) AS year,
       EXTRACT(MONTH FROM ordered_at) AS month,
       EXTRACT(DOW   FROM ordered_at) AS day_of_week  -- 0=domenica
FROM   orders;

The most used parts: YEAR, MONTH, DAY, HOUR, MINUTE, DOW (day of week 0-6), DOY (day of the year).

DATE_TRUNC — rounding down

DATE_TRUNC('part', date) "truncates" the date to a granularity. It is essential for aggregating by month, week, hour:

SQL
-- Tutti gli ordini fatti in "marzo 2025" cadono nello stesso bucket:
SELECT DATE_TRUNC('month', ordered_at) AS month,
       COUNT(*) AS order_count
FROM   orders
GROUP BY month
ORDER BY month;

Valid parts: 'year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second'.

For readability, people often cast to DATE when time is not needed: DATE_TRUNC('month', ordered_at)::date.

Differences and intervals

Subtracting two TIMESTAMPs produces an INTERVAL:

SQL
SELECT id,
       shipped_at - ordered_at AS wait_time
FROM   orders
WHERE  shipped_at IS NOT NULL;

Comparisons with an INTERVAL literal:

SQL
WHERE  shipped_at - ordered_at > INTERVAL '1 day'

Adding days to a date:

SQL
SELECT signed_up_on + INTERVAL '30 days' AS trial_expiration
FROM   customers;

Try it

تمرين#sql.m6.l2.e1
المحاولات: 0جارٍ التحميل…

Count how many orders were placed per year. Two columns: year (integer) and order_count. Order by year ascending.

جارٍ تحميل المحرر…
إظهار التلميح

EXTRACT(YEAR FROM ordered_at) returns a NUMERIC: cast it to int with ::int for readability.

الحل متاح بعد 3 من المحاولات

Review exercise

تمرين#sql.m6.l2.e2
المحاولات: 0جارٍ التحميل…

For each month of 2024, show the first day of the month (column month, of type date) and the number of orders. Order by month.

جارٍ تحميل المحرر…
إظهار التلميح

DATE_TRUNC('month', ordered_at) returns the first day of the month as a timestamp; ::date converts it to date.

الحل متاح بعد 3 من المحاولات