模块 6 · 第 2 课(共 4)课程中的22/57~12 min
模块课程(2/4)
日期和时间戳函数
日期和时间戳无处不在:订单、登录、事件、账单。在 本课我们将了解如何从日期(年、月……)中提取部分, 将其截断到一定粒度(月、周……),计算间隔 和差异,并进行不同时期的比较。
基本类型
PostgreSQL 的区别:
DATE— 仅日期,格式YYYY-MM-DD;TIMESTAMP— 日期+时间,无时区;TIMESTAMPTZ— 日期+时间+时区;INTERVAL— 句点(例如'3 days'、'2 hours 30 minutes')。
在我们的 ecommerce 数据集中:
| 专栏 | 类型 |
|---|---|
customers.signed_up_on | DATE |
orders.ordered_at | orders.ordered_at TIMESTAMP |
orders.shipped_at | TIMESTAMP(可以是NULL) |
EXTRACT — 阅读一部分
EXTRACT(part FROM date) 提取一个数字:
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;最常用的部分:YEAR、MONTH、DAY、HOUR、MINUTE、DOW(天)
第 0-6 周),DOY(一年中的某一天)。
DATE_TRUNC — 向下舍入
DATE_TRUNC('part', date) 将日期“截断”到一定粒度。它是
按月、周、小时聚合的必要:
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;有效部分:'year'、'quarter'、'month'、'week'、'day'、
'hour'、'minute'、'second'。
为了可读性,当不需要时间时,人们经常转换为 DATE :
DATE_TRUNC('month', ordered_at)::date。
差异和间隔
减去两个 TIMESTAMP 会产生 INTERVAL:
SQL
SELECT id,
shipped_at - ordered_at AS wait_time
FROM orders
WHERE shipped_at IS NOT NULL;与 INTERVAL 文字的比较:
SQL
WHERE shipped_at - ordered_at > INTERVAL '1 day'向日期添加天数:
SQL
SELECT signed_up_on + INTERVAL '30 days' AS trial_expiration
FROM customers;尝试一下
锻炼#sql.m6.l2.e1
尝试:0加载中...
计算每年有多少订单。两列:年份(整数)和订单计数。按年份升序排列。
正在加载编辑器...
显示提示
EXTRACT(YEAR FROMordered_at) 返回一个 NUMERIC:使用 ::int 将其转换为 int 以提高可读性。
3 次尝试后可用的解决方案
复习练习
锻炼#sql.m6.l2.e2
尝试:0加载中...
对于 2024 年的每个月,显示该月的第一天(列月份,类型为日期)和订单数。按月订购。
正在加载编辑器...
显示提示
DATE_TRUNC('month',ordered_at) 返回该月的第一天作为时间戳; ::date 将其转换为日期。
3 次尝试后可用的解决方案