CodeGym /课程 /SQL SELF /提取日期部分:EXTRACT() 和 AGE()

提取日期部分:EXTRACT() 和 AGE()

SQL SELF
第 31 级, 课程 2
可用

今天我们继续深入玩时间数据,学会怎么用 EXTRACT() 从里面抠出具体的部分(比如年份、月份或者星期几),还要看看怎么用 AGE() 算年龄或者两个日期之间的间隔。

在实际项目里,处理时间数据经常需要把日期或时间拆开来用。比如:

  • 按年份或月份把订单分组;
  • 统计某个星期几注册的用户数量;
  • 分析两个事件之间的持续时间。

这些需求我们都可以用 EXTRACT() 和 AGE() 这俩函数搞定。

啥是 EXTRACT()?

EXTRACT() 这个函数能从日期或时间戳里抠出你想要的那一部分。比如你可以拿到生日的年份、月份,甚至星期几。

语法:

EXTRACT(part FROM source)
  • part:你想提取的日期部分。可以是 YEAR、MONTH、DAY、HOUR、MINUTE、SECOND 等等。
  • source:你要提取信息的时间类型数据。可以是表里的字段、常量或者函数的结果。

例子1:提取年、月、日

SELECT
    EXTRACT(YEAR FROM '2024-11-15'::DATE) AS year_part,
    EXTRACT(MONTH FROM '2024-11-15'::DATE) AS month_part,
    EXTRACT(DAY FROM '2024-11-15'::DATE) AS day_part;

结果:

year_part month_part day_part
2024 11 15

这里我们从 2024-11-15 这天提取了年、月、日。这个方法很适合你要按日期的某一部分分组数据的时候用。

例子2:提取星期几和小时

SELECT
    EXTRACT(DOW FROM '2024-11-15'::DATE) AS day_of_week,
    EXTRACT(HOUR FROM '15:30:00'::TIME) AS hour_part;

结果:

day_of_week hour_part
3 15
  • DOW (Day of Week) 返回星期几的编号:周日是 0,周一是 1,以此类推。
  • HOUR 就是从时间里抠出小时数。

例子3:对表字段用 EXTRACT()

假如我们有个带日期的表,比如 orders:

order_id order_date
1 2023-05-12 14:20
2 2023-06-18 10:45
3 2023-07-22 21:15
SELECT
    order_id,
    EXTRACT(MONTH FROM order_date) AS month,
    EXTRACT(DAY FROM order_date) AS day
FROM orders;

结果:

order_id month day
1 5 12
2 6 18
3 7 22

啥是 AGE()?

AGE() 这个函数用来算两个时间戳之间的差值。比如你可以用它算客户的年龄,或者某个订单到现在过了多久。

语法:

AGE(timestamp1, timestamp2)
  • timestamp1:较晚的时间戳。
  • timestamp2:较早的时间戳。
  • 如果只写一个参数,PostgreSQL 会自动用当前时间(NOW())和它比。

例子1:算年龄

SELECT AGE('2025-11-15'::DATE, '1990-05-12'::DATE) AS age;

结果:

age
35 years 6 mons

这个例子就是算一个 1990 年 5 月 12 日出生的人,到 2025 年 11 月 15 日的年龄。

例子2:算事件间隔

SELECT AGE('2023-06-01 15:00'::TIMESTAMP, '2023-05-20 10:30'::TIMESTAMP) AS duration;

结果:

duration
11 days 4:30:00

这里我们算了两个事件之间的时间间隔。比如你要算任务开始到结束用了多久,这就很方便。

例子3:客户年龄

假如我们有个 customers 表:

customer_id birth_date
1 1992-03-10
2 1985-07-07

我们可以这样算客户的年龄:

SELECT
    customer_id,
    AGE(NOW(), birth_date) AS age
FROM customers;

2025年6月13日的结果:

customer_id age
1 33 years 3 mons
2 39 years 11 mons

当然你自己的 NOW() 值和结果会不一样哈。

EXTRACT() 和 AGE() 的实用例子

现在我们把这俩函数放到实际场景里玩玩。

例子1:按月份分组统计

假如有个订单表带日期,想统计每月订单数,可以这样写:

SELECT
    EXTRACT(MONTH FROM order_date) AS order_month,
    COUNT(*) AS total_orders
FROM orders
GROUP BY order_month
ORDER BY order_month;

例子2:距离到期还有几天

比如有个 subscriptions 表:

subscription_id expiry_date
1 2023-12-31
2 2024-05-15

我们想知道每个订阅距离到期还有多久:

SELECT
    subscription_id,
    AGE(expiry_date, NOW()) AS time_remaining
FROM subscriptions;

结果:

subscription_id time_remaining
1 1 mons 15 days
2 6 mons

常见坑和怎么避开

用 EXTRACT() 和 AGE() 的时候,新手经常会踩这些坑:

  • 想从 TIME 类型里抠月份啥的,这不行。记住:YEAR、MONTH、DAY 这些只能用在 DATE、TIMESTAMP,不能用在 TIME。
  • 时间数据格式不对。比如 2023/11/15 这种字符串不是标准日期。要用 ::DATE 或 TO_DATE() 转一下类型。
  • AGE() 和直接减时间戳的区别。如果你要精确的间隔(比如几个月、几天、几秒)用 AGE(),要是只想知道天数,直接减就行。

现在你已经有了用 PostgreSQL 提取和分析时间数据的所有技能。赶紧在自己的项目里试试 EXTRACT() 和 AGE() 吧!

2
任务
SQL SELF, 第 31 级, 课程 2
已锁定
计算客户截至当前日期的年龄
计算客户截至当前日期的年龄
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION