如何实现每种类型各获取2条数据表记录的查询?
每种类型返回恰好2条记录的SQL解决方案
嘿,这个需求其实挺常见的,不同数据库有不同的实现方案,我给你整理了几种主流数据库的写法,你可以根据自己的环境来选:
MySQL/MariaDB(8.0及以上版本)
用窗口函数ROW_NUMBER()是最直观的方式,它能帮你按类型分组后给每条记录编号,然后筛选出前2条:
SELECT * FROM ( SELECT *, -- 按type分组,每组内按你指定的字段排序(比如创建时间、ID),生成序号 ROW_NUMBER() OVER (PARTITION BY type ORDER BY create_time) AS rn FROM your_table ) t WHERE rn <= 2;
如果想随机获取每组的2条记录,把ORDER BY create_time换成ORDER BY RAND()就行,但注意大数据量下RAND()效率会偏低。
PostgreSQL
和MySQL的窗口函数用法几乎一致,只是随机排序用random():
SELECT * FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY type ORDER BY id) AS rn FROM your_table ) sub WHERE rn <= 2;
SQL Server
同样依赖窗口函数,写法大同小异:
SELECT * FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY type ORDER BY update_time) AS rn FROM your_table ) temp WHERE rn <= 2;
老版本MySQL(8.0以下,无窗口函数)
如果你的MySQL版本不支持窗口函数,可以用变量来实现分组计数:
SELECT * FROM ( SELECT *, -- 当type和上一条相同时序号+1,否则重置为1 @rn := IF(@current_type = type, @rn + 1, 1) AS rn, @current_type := type FROM your_table, -- 初始化变量 (SELECT @current_type := '', @rn := 0) vars -- 必须先按type排序,保证变量能正确分组 ORDER BY type, id ) t WHERE rn <= 2;
补充说明
以上所有方案都能自动处理“某类型记录不足2条”的情况——如果某个type只有1条或0条记录,会返回所有存在的记录,不会报错。
内容的提问来源于stack exchange,提问作者Andreas B
相关产品推荐
相关产品推荐

