我有一张学生桌,上面有这样的临时测试值:
表学生
+----+-------------+-------+-----------+
| 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 |
+----+-------------+-------+-----------+
我想查询表格,以便获得每个部分的所有最大年龄。但是,如果两个学生的年龄相同,则生成的表将返回ID最小的学生。
返回:
+----+------------+-----+--------+
| id | section_id | age | name |
+----+------------+-----+--------+
| 1 | 1 | 18 | Justin |
+----+------------+-----+--------+
| 3 | 2 | 16 | Cherry |
+----+------------+-----+--------+
| 5 | 3 | 21 | Marie |
+----+------------+-----+--------+
我尝试了以下查询:
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
不幸的是,有些实例的ID与年龄和名称不匹配。
我要结束了:
sql_mode = only_full_group_by
而且我没有权限对其进行编辑,因此any_value函数但是我不知道如何使用它。
答案 0 :(得分:1)
这会做你想要的。
首先查找每节的最大年龄(包括重复项)。 然后将这些结果与每个部分的ID最小化(以消除重复)。 最后,为匹配的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);
有效的SQL提琴:https://www.db-fiddle.com/f/aezgAYM6A5KnXykceB7At1/0
答案 1 :(得分:1)
我只使用相关子查询:
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
);
这几乎是表达逻辑的最简单方法。并且使用students(section, age, id)
上的索引,它也应该是性能最高的。