首页 >> 基础教程

sql技巧-每个班年龄排前两名的人

 MySQL 8 及以上版本可以用下面sql语句:

SELECT 
    class_id,
    student_name,
    age
FROM (
    SELECT 
        class_id,
        student_name,
        age,
        -- 按班级分组,按年龄降序排序,年龄相同按学号升序(或其他字段)
        ROW_NUMBER() OVER (
            PARTITION BY class_id 
            ORDER BY age DESC, student_id ASC
        ) AS rn    
    FROM students) AS ranked
WHERE rn <= 2; -- 取每班前两名


mysql5.6及以下版本

1、使用子查询

SELECT 
    s1.class_id,
    s1.student_name,
    s1.age
FROM students s1
WHERE (
    SELECT COUNT(DISTINCT s2.age) 
    FROM students s2 
    WHERE s2.class_id = s1.class_id 
      AND s2.age >= s1.age) <= 2
ORDER BY s1.class_id, s1.age DESC, s1.student_id;

2、使用union all

-- 第一名(包含并列)
SELECT * FROM students s1
WHERE age = (
    SELECT MAX(age) 
    FROM students s2 
    WHERE s2.class_id = s1.class_id)
UNION ALL
-- 第二名(排除第一名后取最高)
SELECT * FROM students s1WHERE age = (
    SELECT MAX(age) 
    FROM students s2 
    WHERE s2.class_id = s1.class_id 
      AND age < (
          SELECT MAX(age) 
          FROM students s3 
          WHERE s3.class_id = s1.class_id
          )
)
ORDER BY class_id, age DESC;

3、使用一个临时表

最后这个方法是新增个字段各班年龄排序字段rank,可以查询

select * from students where rank<=2


发表评论

昵称:
联系方式:
评论内容:

所有评论

最新文章
10.5 反规范化:什么时候需要打破规则?2026-03-22
10.4 第三范式(3NF)2026-03-22
10.3 第二范式(2NF)2026-03-22
10.2 第一范式(1NF)2026-03-22
10.1 什么是数据库规范化?2026-03-22
9.5 实践:电商系统表关系设计2026-03-22
9.4 实际案例:博客系统表设计2026-03-22
9.3 多对多关系2026-03-22
9.2 一对多关系2026-03-22
9.1 一对一关系2026-03-18
关于我 备案号:蜀ICP备2023042032号-1