抓取每个分组结果中的前n条记录
P粉785957729
P粉785957729 2023-08-21 19:55:22
[MySQL讨论组]

以下是最简单的可能示例,但任何解决方案都应能够扩展到所需的n个顶部结果:

给定如下表格,其中包含人员、组和年龄列,如何获取每个组中年龄最大的2个人?(组内的并列情况不应产生更多结果,而是按字母顺序给出前2个)

+--------+-------+-----+
| Person | Group | Age |
+--------+-------+-----+
| Bob    | 1     | 32  |
| Jill   | 1     | 34  |
| Shawn  | 1     | 42  |
| Jake   | 2     | 29  |
| Paul   | 2     | 36  |
| Laura  | 2     | 39  |
+--------+-------+-----+

期望的结果集:

+--------+-------+-----+
| Shawn  | 1     | 42  |
| Jill   | 1     | 34  |
| Laura  | 2     | 39  |
| Paul   | 2     | 36  |
+--------+-------+-----+

注意:这个问题是基于之前的一个问题——获取每个组的最大值的记录的SQL结果 - 用于获取每个组的单个顶部行,并且从@Bohemian获得了一个很好的MySQL特定的答案:

select * 
from (select * from mytable order by `Group`, Age desc, Person) x
group by `Group`

很想能够在此基础上继续构建,但我看不出如何做到。

P粉785957729
P粉785957729

全部回复(2)
P粉340264283

在其他数据库中,您可以使用ROW_NUMBER来实现此功能。MySQL不支持ROW_NUMBER,但您可以使用变量来模拟它:

SELECT
    person,
    groupname,
    age
FROM
(
    SELECT
        person,
        groupname,
        age,
        @rn := IF(@prev = groupname, @rn + 1, 1) AS rn,
        @prev := groupname
    FROM mytable
    JOIN (SELECT @prev := NULL, @rn := 0) AS vars
    ORDER BY groupname, age DESC, person
) AS T1
WHERE rn <= 2

在线演示: sqlfiddle


编辑 我刚刚注意到bluefeet发布了一个非常相似的答案:给他+1。但是这个答案有两个小优点:

  1. 这是一个单一查询。变量在SELECT语句内部初始化。
  2. 它处理了问题中描述的并列情况(按名称的字母顺序)。

因此,我将保留它,以防它能帮助到某人。

P粉404539732

以下是一种方法,使用UNION ALL(请参见带有演示的SQL Fiddle)。这适用于两个组,如果你有多个组,则需要指定group编号并为每个group添加查询:

(
  select *
  from mytable 
  where `group` = 1
  order by age desc
  LIMIT 2
)
UNION ALL
(
  select *
  from mytable 
  where `group` = 2
  order by age desc
  LIMIT 2
)

有多种方法可以实现这个目标,请参考本文以确定适合您情况的最佳方法:

http://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/

编辑:

这也可能适用于您,它为每条记录生成一个行号。使用上面链接中的示例,它将仅返回行号小于或等于2的记录:

select person, `group`, age
from 
(
   select person, `group`, age,
      (@num:=if(@group = `group`, @num +1, if(@group := `group`, 1, 1))) row_number 
  from test t
  CROSS JOIN (select @num:=0, @group:=null) c
  order by `Group`, Age desc, person
) as x 
where x.row_number <= 2;

请参见演示

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号