日期函数

SQL 笔试与手撕题教程

面试提醒
日期函数本身不难,难的是跟业务结合。比如广告归因的"点击后 30 分钟内下单"——面试官考的不只是 TIMESTAMPDIFF 语法,更看你能不能理解归因窗口这个业务概念。

提取时间部分

从日期/时间字段里提取年、月、日:

YEAR(date)
MONTH(date)
DAY(date)
DATE_FORMAT(date, '%Y-%m')   -- 输出如 '2026-04'

以上函数均为 MySQL 原生语法,本页练习直接在 MySQL 中运行。

日期运算

-- 日期加减
DATE_ADD(order_time, INTERVAL 30 MINUTE)
DATE_SUB(order_time, INTERVAL 1 DAY)

-- 计算间隔
DATEDIFF(date1, date2)              -- 返回天数差
TIMESTAMPDIFF(MINUTE, t1, t2)       -- 精确到指定单位

DATEDIFF 只能算天数,TIMESTAMPDIFF 可以指定 SECOND、MINUTE、HOUR、DAY 等单位。需要精确到分钟或秒的场景用后者。

实战:广告点击归因

判断用户点击广告后 30 分钟内是否下了单:

SELECT
    T1.user_id,
    T1.click_time,
    CASE
        WHEN MIN(TIMESTAMPDIFF(MINUTE, T1.click_time, T2.order_time)) <= 30
        THEN 1 ELSE 0
    END AS if_order
FROM ad_clicks T1
JOIN orders T2
    ON T1.user_id = T2.user_id
    AND T2.order_time BETWEEN T1.click_time
        AND T1.click_time + INTERVAL 30 MINUTE
GROUP BY T1.user_id, T1.click_time;

核心思路:BETWEEN + INTERVAL 限定时间窗口,MIN() + CASE 判断是否存在窗口内的订单。

练习

练习

相邻下单最大间隔

给定 orders 表,找出每个用户两次相邻下单之间的最大间隔天数。只下过一单的用户不需要输出。

提示:用 LAG 取前一次下单日期,再求每个用户的 MAX 间隔

SQL 编辑器

点击「运行」查看查询结果

查看答案
参考答案
SELECT user_id, MAX(gap) AS max_gap_days
FROM (
  SELECT user_id, order_date,
    DATEDIFF(order_date, LAG(order_date) OVER(PARTITION BY user_id ORDER BY order_date)) AS gap
  FROM orders
) t
WHERE gap IS NOT NULL
GROUP BY user_id;
解析

LAG 取前一次下单日期,DATEDIFF(date1, date2) 返回天数差。第一笔订单的 LAG 为 NULL,DATEDIFF 结果也为 NULL,WHERE gap IS NOT NULL 自动排除只下过一单的用户。

练习

月度登录天数

给定 logins 表(同一天可能有多条记录),按月统计每个用户的登录天数。

提示:先对 user_id + 日期去重,再按月分组 COUNT

SQL 编辑器

点击「运行」查看查询结果

查看答案
参考答案
SELECT user_id,
  DATE_FORMAT(login_time, '%Y-%m') AS month,
  COUNT(DISTINCT DATE(login_time)) AS login_days
FROM logins
GROUP BY user_id, DATE_FORMAT(login_time, '%Y-%m');
解析

DATE(login_time) 截取日期部分(如 '2026-04-01'),COUNT(DISTINCT ...) 对同一天去重。DATE_FORMAT(login_time, '%Y-%m') 提取年月用于分组。