【发布时间】:2018-04-08 02:50:23
【问题描述】:
我有一个包含以下列的表格:id、status、value。
id status value
-- ------ -----
1 10 100
2 10 100
3 10 60
4 11 20
5 11 15
6 12 100
7 12 50
8 12 50
我想从每个状态组中获取第一和第二高值行的 id 和值。我的表应该有以下列:
状态,第一高的id,第一高的,第二高的id,第二高的。
我应该得到:
status 1stID 1stValue 2ndID 2ndValue
------ ----- -------- ----- --------
10 1/2 100 2/1 100
11 4 20 5 15
12 6 100 7/8 50
我尝试了各种解决方案,但我找不到相同值 1st s(具有相同值的两行,恰好是该状态组中的最高值)或相同值秒的解决方案。
例如,如果两行共享其状态组中的最高值,这个不太优雅的查询将返回两行具有相同状态、不同的第一个和相同的第二个:
SELECT 2nds.status, 1sts.id AS "1stID",1sts.value AS "1stValue",
2nds.id AS "2ndID",2nds.value AS "2ndValue"
FROM
(SELECT v.* FROM
(SELECT status, MAX(value) AS "SecMaxValue" FROM table o
WHERE value < (SELECT MAX(value) FROM table
WHERE status = o.status
GROUP BY status) AS m
INNER JOIN table v
ON v.status = m.status AND v.value = m.SecMaxValue) AS 2nds
INNER JOIN
(SELECT v.* FROM
(SELECT status, MAX(value) AS maxValue FROM table
GROUP BY status) AS m
INNER JOIN table v
ON v.status = m.status AND v.value = m.MaxValue) AS 1sts
ON 1sts.status = 2nds.status ;
这个查询会给我:
status 1stID 1stValue 2ndID 2ndValue
------ ----- -------- ----- --------
10 1 100 3 60
10 2 100 3 60
11 4 20 5 15
12 6 100 7 50
12 6 100 8 50
最后,我想找到一个解决方案: 一种。如果有两行具有最高值,则查询将其中一个的详细信息放在第 1 列中,将其他的详细信息放在第 2 列中(不是哪个) 湾。如果有两行具有第二高值,则将最高值放在其位置,将秒数之一放在第二位置。
有没有办法改变上面的查询?有人有更好的解决方案吗?
- 我遇到了几个第一个和第二个查询,但他们有同样的问题 - 例如这个解决方案:Finding the highest n values of each group in MySQL。它不会在同一行中提供第一名和第二名,但主要问题是它只提供了第一名。
谢谢
【问题讨论】:
-
请以正确的格式提供样本数据、当前和期望的结果。这将非常有帮助。
-
一旦人们升级到 MySQL 8.0,这种问题就会变得如此简单。只需使用RANK() window function。
-
@BillKarwin 谢谢你的信息。我不知道 Mysql 中也引入了
rank()和dense_rank()。是的,当然,这些功能将使这项任务变得比现在更简单。