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

如何用单条SQL语句查询MySQL中每个班级的首个和最后一个事件?

解决方案:查询每个班级的首个和最后一个事件

方法一:使用窗口函数(MySQL 8.0+ 推荐)

利用ROW_NUMBER()窗口函数为每个班级的事件按日期排序并编号,筛选出编号为1的首末事件:

WITH ranked_events AS (
    SELECT 
        classId,
        date,
        message,
        ROW_NUMBER() OVER (PARTITION BY classId ORDER BY date ASC) AS rn_asc,
        ROW_NUMBER() OVER (PARTITION BY classId ORDER BY date DESC) AS rn_desc
    FROM events
)
SELECT classId, date, message
FROM ranked_events
WHERE rn_asc = 1 OR rn_desc = 1
ORDER BY classId, date;

如果班级仅存在一个事件,该记录会同时满足rn_asc=1和rn_desc=1,因此会返回两次。若希望只返回一次,可在SELECT后添加DISTINCT关键字。

方法二:兼容旧版本MySQL(5.7及以下)

通过子查询获取每个班级的最早和最晚日期,再关联原表筛选对应事件:

SELECT e.classId, e.date, e.message
FROM events e
INNER JOIN (
    SELECT 
        classId,
        MIN(date) AS first_date,
        MAX(date) AS last_date
    FROM events
    GROUP BY classId
) AS class_dates 
ON e.classId = class_dates.classId 
AND (e.date = class_dates.first_date OR e.date = class_dates.last_date)
ORDER BY e.classId, e.date;

注意:若同一班级在最早/最晚日期存在多条事件,该方法会返回所有对应日期的事件。若需仅返回单条,可结合GROUP BY e.classId, e.date或添加额外排序条件。

可选:首末事件同行展示

若希望将每个班级的首末事件信息放在同一行,可使用条件聚合:

SELECT 
    classId,
    MAX(CASE WHEN rn_asc = 1 THEN date END) AS first_date,
    MAX(CASE WHEN rn_asc = 1 THEN message END) AS first_message,
    MAX(CASE WHEN rn_desc = 1 THEN date END) AS last_date,
    MAX(CASE WHEN rn_desc = 1 THEN message END) AS last_message
FROM (
    SELECT 
        classId,
        date,
        message,
        ROW_NUMBER() OVER (PARTITION BY classId ORDER BY date ASC) AS rn_asc,
        ROW_NUMBER() OVER (PARTITION BY classId ORDER BY date DESC) AS rn_desc
    FROM events
) AS ranked
GROUP BY classId;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 12:25:25