You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

按日期和用户分组获取首个与最后一个job_id

按用户和日期分组获取每日首个与最后一个job_id

我有两张表:jobs和users

jobs表结构示例

idcreated_at
4442022-12-12 08:00:00
3332022-12-12 09:00:00
2222022-12-12 10:00:00
5552022-12-12 07:00:00
1112022-12-12 12:00:00
8882022-12-12 08:00:00

users表结构示例

iduser_idjob_id
12111
21222
31333
41444
52555
62888

我需要按日期和用户分组,在同一行中获取每个用户每日的首个job_id和最后一个job_id,预期结果如下:

预期结果

user_iddatefirst_idlast_id
12022-12-12444222
22022-12-12555111

解决方案

可以通过关联两张表,结合窗口函数实现需求,以下提供两种兼容主流数据库的写法:

写法一:基于ROW_NUMBER()分组筛选

WITH job_user AS (
    SELECT 
        u.user_id,
        DATE(j.created_at) AS date,
        j.id AS job_id,
        -- 按创建时间升序标记行号
        ROW_NUMBER() OVER (PARTITION BY u.user_id, DATE(j.created_at) ORDER BY j.created_at ASC) AS rn_asc,
        -- 按创建时间降序标记行号
        ROW_NUMBER() OVER (PARTITION BY u.user_id, DATE(j.created_at) ORDER BY j.created_at DESC) AS rn_desc
    FROM users u
    JOIN jobs j ON u.job_id = j.id
)
SELECT 
    user_id,
    date,
    MAX(CASE WHEN rn_asc = 1 THEN job_id END) AS first_id,
    MAX(CASE WHEN rn_desc = 1 THEN job_id END) AS last_id
FROM job_user
GROUP BY user_id, date;

写法二:基于FIRST_VALUE()/LAST_VALUE()窗口函数

SELECT DISTINCT
    u.user_id,
    DATE(j.created_at) AS date,
    FIRST_VALUE(j.id) OVER (
        PARTITION BY u.user_id, DATE(j.created_at) 
        ORDER BY j.created_at ASC
    ) AS first_id,
    LAST_VALUE(j.id) OVER (
        PARTITION BY u.user_id, DATE(j.created_at) 
        ORDER BY j.created_at ASC
        ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
    ) AS last_id
FROM users u
JOIN jobs j ON u.job_id = j.id;

两种写法均能得到预期结果,写法一兼容更多数据库版本,写法二适合支持完整窗口函数特性的数据库(如MySQL 8.0+、PostgreSQL等)。

内容的提问来源于stack exchange,提问作者madeye

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 15:20:22