简体   繁体   English

MySQL查询按部分获取最大年龄,如果两个或多个具有相同年龄,则返回ID最小的学生

[英]Mysql query to get max age by section and if two or more has same age return student with smallest id

I have a table of students with temporary test values like this: 我有一张带有临时测试值的学生表,如下所示:

Table students 学生

+----+-------------+-------+-----------+
| id | section_id  |  age  | name      |
+----+-------------+-------+-----------+
| 1  | 1           | 18    | Justin    |
+----+-------------+-------+-----------+
| 2  | 2           | 14    | Jillian   |
+----+-------------+-------+-----------+
| 3  | 2           | 16    | Cherry    |
+----+-------------+-------+-----------+
| 4  | 3           | 19    | Ronald    |
+----+-------------+-------+-----------+
| 5  | 3           | 21    | Marie     |
+----+-------------+-------+-----------+
| 6  | 3           | 21    | Arthur    |
+----+-------------+-------+-----------+

I want to query the table such that I want to get all the maximum ages of each section. 我想查询表,以便获得每个部分的所有最大年龄。 However, if two students have the same age, the table produced will return the student with smallest id. 但是,如果两个学生的年龄相同,则生成的表将返回ID最小的学生。

Return: 返回:

+----+------------+-----+--------+
| id | section_id | age | name   |
+----+------------+-----+--------+
| 1  | 1          | 18  | Justin |
+----+------------+-----+--------+
| 3  | 2          | 16  | Cherry |
+----+------------+-----+--------+
| 5  | 3          | 21  | Marie  |
+----+------------+-----+--------+

I tried this query: 我试过这个查询:

SELECT ANY_VALUE(id), ANY_VALUE(section_id), MAX(age), ANY_VALUE(name) FROM
(SELECT id, section_id, age, name FROM students ORDER BY id) as X
GROUP BY section_id

Unfortunately, there are instances that id does not match the age and name. 不幸的是,有些实例的ID与年龄和名称不匹配。

I have on my end: 我的目标是:

sql_mode = only_full_group_by

and I don't have a privilege to edit that, hence the any_value function but I have no idea how to use it. 而且我没有特权对其进行编辑,因此any_value函数但是我不知道如何使用它。

This will do what you want. 这将做您想要的。

It starts by finding the maximum age per section (including duplicates). 首先要找到每节的最大年龄(包括重复项)。 Then it joins those results with the minimum id per section (to eliminate duplicates). 然后将这些结果与每个部分的ID最小化(以消除重复)。 And finally, select all fields for the matching id and section combinations. 最后,为匹配的ID和部分组合选择所有字段。

SELECT s3.*
FROM students s3
INNER JOIN (
    SELECT MIN(s2.id) AS id, s2.section_id
    FROM students s2
    INNER JOIN (
        SELECT s1.section_id, MAX(s1.age) AS age
        FROM students s1
        GROUP BY s1.section_id  
    ) s1 USING (section_id, age)
    GROUP BY s2.section_id
) s2 USING (id, section_id);

Working SQL fiddle: https://www.db-fiddle.com/f/aezgAYM6A5KnXykceB7At1/0 有效的SQL提琴: https : //www.db-fiddle.com/f/aezgAYM6A5KnXykceB7At1/0

I would simply use a correlated subquery: 我只会使用相关的子查询:

select s.*
from students s
where s.id = (select s2.id
              from students s2
              where s2.section_id = s.section_id
              order by s2.age desc, s2.id asc
              limit 1
             );

This is pretty much the simplest way to express the logic. 这几乎是表达逻辑的最简单方法。 And with an index on students(section, age, id) , it should be the most performant as well. 并且根据students(section, age, id)的指数,它也应该是表现最好的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM