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

MySQL单表双参数查询及多日期提取技术问题求助

解决MySQL同表分组后筛选晚于组内首次日期的记录问题

我明白你的需求了——要按mc_id和op_id分组,先确定每组的首个(最早)done_on_date作为基准,再找出该组里所有晚于这个基准日期的done_on_date记录。下面给你两种实用的实现方案:

方法1:用窗口函数(MySQL 8.0+优先推荐)

窗口函数能高效地为每条记录计算其所属分组的基准日期,无需额外关联,性能更优:

SELECT 
    mc_id,
    op_id,
    vouid,
    done_on_date,
    first_done_date  -- 该组的首次提取日期
FROM (
    SELECT 
        *,
        MIN(done_on_date) OVER (PARTITION BY mc_id, op_id) AS first_done_date
    FROM your_table  -- 替换成你的实际表名
) AS sub_query
WHERE done_on_date > first_done_date;

逻辑解释:

  • MIN(done_on_date) OVER (PARTITION BY mc_id, op_id):通过PARTITION BY按mc_id和op_id分组,计算每组的最小(最早)done_on_date,命名为first_done_date。
  • 外层查询筛选出done_on_date大于该组基准日期的记录,就是你要的晚于首次提取日期的结果。

方法2:子查询关联(兼容MySQL 5.x版本)

如果你的MySQL版本低于8.0,不支持窗口函数,可以用子查询先获取每组基准日期,再关联原表筛选:

SELECT 
    t.mc_id,
    t.op_id,
    t.vouid,
    t.done_on_date,
    g.first_done_date
FROM your_table t  -- 替换成你的实际表名
JOIN (
    SELECT 
        mc_id,
        op_id,
        MIN(done_on_date) AS first_done_date
    FROM your_table  -- 替换成你的实际表名
    GROUP BY mc_id, op_id
) AS g ON t.mc_id = g.mc_id AND t.op_id = g.op_id
WHERE t.done_on_date > g.first_done_date;

逻辑解释:

  • 子查询g先按mc_id和op_id分组,算出每组的最早done_on_date。
  • 将原表t和子查询g关联,筛选出原表中日期晚于分组基准日期的记录。

特殊场景调整

如果你的“首次提取日期”不是分组的最早日期,而是该组中某个特定vouid对应的日期,可以修改成下面的逻辑:

-- 示例:以vouid=123的日期作为该组的基准日期
SELECT 
    t.mc_id,
    t.op_id,
    t.vouid,
    t.done_on_date,
    g.target_date
FROM your_table t
JOIN (
    SELECT 
        mc_id,
        op_id,
        done_on_date AS target_date
    FROM your_table
    WHERE vouid = 123  -- 替换成你指定的vouid
) AS g ON t.mc_id = g.mc_id AND t.op_id = g.op_id
WHERE t.done_on_date > g.target_date;

你可以根据实际表结构和需求,替换掉SQL里的表名、字段名即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:25:30