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

如何在MariaDB中高效合并同组用户的日期记录?

问题

我有一组用户记录,包含started(开始日期)、ends(结束日期)以及用户所属分组A、B、C,具体数据如下:

startedendsABC
2010/01/022010/02/02101
2010/03/022010/04/02101
2010/05/022010/06/02101
2011/01/022011/02/02001
2011/03/022011/04/02001

使用MariaDB,需要将同一分组(A、B、C取值完全相同)的记录合并为一条,取该分组下最早的started日期和最晚的ends日期,预期合并结果如下:

startedendsABC
2010/01/022010/06/02101
2011/01/022011/04/02001

当前用存储过程+游标+临时表的方式实现,耗时较长,代码如下:

CREATE PROCEDURE loopOver()
BEGIN
    DECLARE done BOOLEAN DEFAULT 0;
    DECLARE id BIGINT UNSIGNED;

    DECLARE cur CURSOR FOR SELECT user_id
                          FROM table1 as f
                          WHERE NOT EXISTS( -- temp table that contain already check records
                                  SELECT 1
                                  FROM temp_table as t
                                  WHERE f.id = t.id);
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

    OPEN cur;
    FETCH cur INTO id;  -- Get first row
    WHILE NOT done
        DO
           -- This where i create tmp table
            call creating_tmp_table(id); 
            FETCH cur INTO id;  -- Get next row
        END WHILE;
    CLOSE cur;
END //

请问有没有更高效的实现方式?

更高效的实现方案

不需要用游标和临时表,直接用分组聚合查询就能完成需求,这是数据库原生优化的高效操作,完全避免游标逐行处理的性能损耗。

基础实现SQL

SELECT
    MIN(started) AS started,
    MAX(ends) AS ends,
    A,
    B,
    C
FROM table1
GROUP BY A, B, C;

关键说明

  1. 核心逻辑:通过GROUP BY A, B, C将所有分组完全相同的记录归为一组,再用MIN(started)取组内最早开始日期,MAX(ends)取组内最晚结束日期,直接得到预期的合并结果。
  2. 性能优势:分组聚合是数据库底层优化过的批量操作,数据量越大,对比游标逐行处理的速度差距越明显。
  3. 日期类型兼容:如果started和ends是字符串格式,建议先转换为日期类型再聚合,确保日期比较的准确性:
SELECT
    MIN(STR_TO_DATE(started, '%Y/%m/%d')) AS started,
    MAX(STR_TO_DATE(ends, '%Y/%m/%d')) AS ends,
    A,
    B,
    C
FROM table1
GROUP BY A, B, C;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 05:25:40