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

MySQL 5.7如何按company_id分组获取最新一条有效数据

MySQL 5.7.39 按company_id获取最新createdAt记录的实现方案

问题背景

需要从subscription表中,为指定的company_id(16867、19164)各选取一条createdAt最新的记录,筛选条件为disabledAt IS NULL。

原查询及结果

执行以下SQL获取所有符合条件的记录:

SELECT `company_id`, `product_id`, `expiresAt`, `createdAt`, `createdBy`, `disabledAt`
FROM subscription
WHERE `disabledAt` IS NULL AND `company_id` IN(16867, 19164)
ORDER BY `createdAt` DESC;

返回结果:

company_id  product_id  expiresAt   createdAt       createdBy   disabledAt  
19164   3   2023-05-02  2022-06-09 12:41:37 1   NULL    
19164   3   2022-05-02  2022-06-09 12:40:47 1   NULL    
16867   3   2023-05-31  2022-05-20 08:18:36 1   NULL    
16867   3   2023-05-31  2022-05-20 08:18:08 1   NULL    
16867   3   2022-05-31  2022-05-12 14:49:51 1   NULL    
16867   3   2022-05-26  2021-05-26 07:20:52 1   NULL

期望结果

每个company_id仅保留createdAt最新的一条记录:

19164   3   2023-05-02  2022-06-09 12:41:37 1    NULL
16867   3   2023-05-31  2022-05-20 08:18:36 1    NULL

错误的GROUP BY尝试

直接使用GROUP BY会返回错误结果,因为MySQL 5.7开启ONLY_FULL_GROUP_BY模式时,SELECT中的非聚合字段必须包含在GROUP BY中,否则会随机返回分组内的某条记录:

SELECT `company_id`, `product_id`, `expiresAt`, `createdAt`, `createdBy`, `disabledAt`
FROM subscription
WHERE `disabledAt` IS NULL AND `company_id` IN(16867, 19164)
GROUP BY `company_id`
ORDER BY `createdAt` DESC;

错误结果:

company_id  product_id  expiresAt   createdAt       createdBy   disabledAt  
19164   3   2022-05-02  2022-06-09 12:40:47 1   NULL    
16867   3   2022-05-26  2021-05-26 07:20:52 1   NULL    

正确实现方案

由于MySQL 5.7不支持窗口函数,可通过以下两种方式实现需求:

方案一:子查询+关联查询

先通过子查询获取每个company_id对应的最新createdAt,再关联原表筛选匹配记录:

SELECT s.`company_id`, s.`product_id`, s.`expiresAt`, s.`createdAt`, s.`createdBy`, s.`disabledAt`
FROM subscription s
INNER JOIN (
    -- 子查询:获取符合条件的每个company_id的最新createdAt
    SELECT `company_id`, MAX(`createdAt`) AS max_createdAt
    FROM subscription
    WHERE `disabledAt` IS NULL AND `company_id` IN(16867, 19164)
    GROUP BY `company_id`
) t ON s.`company_id` = t.`company_id` AND s.`createdAt` = t.max_createdAt
WHERE s.`disabledAt` IS NULL;

方案二:关联子查询筛选

对每条记录,判断其createdAt是否为对应company_id下的最大值:

SELECT `company_id`, `product_id`, `expiresAt`, `createdAt`, `createdBy`, `disabledAt`
FROM subscription s
WHERE `disabledAt` IS NULL 
  AND `company_id` IN(16867, 19164)
  AND `createdAt` = (
      -- 子查询:获取当前company_id下符合条件的最大createdAt
      SELECT MAX(`createdAt`)
      FROM subscription
      WHERE `company_id` = s.`company_id` AND `disabledAt` IS NULL
  );

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 12:52:19