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

MySQL分组查询:如何按姓氏取最新7条记录(最多9个姓氏)

嘿,针对你的这个MySQL查询需求,我来一步步帮你解决,同时也把分组取指定条数记录的通用方法讲清楚——毕竟你的表有10万+数据,得兼顾效率才行。

满足需求的具体SQL实现

首先假设你的id字段是自增的(最新的记录id值最大),我们可以利用MySQL 8.0+支持的窗口函数来高效实现你的需求:

WITH ranked_records AS (
    SELECT 
        id, 
        name, 
        lastname,
        -- 按姓氏分组,每组内按id降序(最新记录在前)给记录编号
        ROW_NUMBER() OVER (PARTITION BY lastname ORDER BY id DESC) AS rn
    FROM your_table_name -- 替换成你的实际表名
),
limited_surnames AS (
    -- 先选出最多9个姓氏,这里按姓氏字母排序,你可以改成按记录数降序等规则
    SELECT DISTINCT lastname
    FROM ranked_records
    ORDER BY lastname
    LIMIT 9
)
-- 关联两个结果集,筛选每个姓氏组内前7条最新记录,且只包含那9个姓氏
SELECT rr.id, rr.name, rr.lastname
FROM ranked_records rr
JOIN limited_surnames ls ON rr.lastname = ls.lastname
WHERE rr.rn <= 7
ORDER BY rr.lastname, rr.rn;

代码解释:

  • ranked_records:用ROW_NUMBER()窗口函数给每个姓氏组的记录编号,rn为1的就是该姓氏最新的记录,以此类推。
  • limited_surnames:先筛选出最多9个目标姓氏,你可以根据需求调整排序逻辑——比如想选记录最多的9个姓氏,把ORDER BY lastname改成ORDER BY (SELECT COUNT(*) FROM your_table_name t WHERE t.lastname = ranked_records.lastname) DESC即可。
  • 最后关联两个结果集,只保留每个姓氏的前7条最新记录。
MySQL分组查询获取指定数量记录的通用方法

下面分两种场景讲解,优先推荐高效的窗口函数方案:

方法1:窗口函数(MySQL 8.0+,强烈推荐)

窗口函数是处理这类分组取数需求的最优解,只需要扫描一次表,性能极佳,适合大数据量场景。常用的窗口函数有三个,可根据你的需求选择:

  • ROW_NUMBER():组内每条记录编号唯一,即使排序字段相同也会按顺序编号(适合你需要严格取前N条的场景)
  • RANK():相同排序字段的记录会有相同编号,下一个编号会跳号(比如两个并列第一,下一个就是第三)
  • DENSE_RANK():相同排序字段的记录编号相同,下一个编号不跳号(两个并列第一,下一个是第二)

通用模板:

WITH ranked_data AS (
    SELECT 
        *,
        ROW_NUMBER() OVER (PARTITION BY 分组字段 ORDER BY 排序字段 DESC/ASC) AS rn
    FROM 你的表名
)
SELECT *
FROM ranked_data
WHERE rn <= N; -- N是每组要取的记录数

优化建议:

给分组字段和排序字段建立联合索引,比如针对你的场景:

CREATE INDEX idx_lastname_id ON your_table_name(lastname, id DESC);

这样窗口函数在分组排序时可以直接利用索引,避免全表扫描,查询速度会快很多。

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

如果你的MySQL版本低于8.0,不支持窗口函数,可以用子查询统计组内当前记录的排名,但这种方法性能很差,不建议用于10万+数据的表:

SELECT t1.*
FROM your_table_name t1
WHERE (
    -- 统计同姓氏中id大于等于当前记录的数量(即当前记录在组内的排名)
    SELECT COUNT(*)
    FROM your_table_name t2
    WHERE t2.lastname = t1.lastname AND t2.id >= t1.id
) <= 7
ORDER BY t1.lastname, t1.id DESC;

这个方法会对每条记录执行一次子查询,数据量大时会非常慢,所以优先建议升级MySQL版本使用窗口函数方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:42:06