mysql - 如果值相似,则获取第一个和第二个最高值行

标签 mysql max

我有一个表,其中包含以下列:id、状态、值。

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 和值。我的表格应包含以下列:
status,第一高值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   

我尝试了各种解决方案,但找不到相同值第一秒(具有相同值的两行,恰好是该状态组中最高的行)或相同值秒的解决方案。

例如,如果两行在其状态组中共享最高值,则这个不太优雅的查询将返回具有相同状态的两行,第一行不同,第二行相同:

    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     

总而言之,我想找到一个解决方案: A。如果有两行具有最高值,则查询将其中之一的详细信息放在第一列中,将其他行的详细信息放在第二列中(不管是哪一列) b.如果有两行具有第二高值,则将最高值放在其位置,并将秒数之一放在第二位。

有没有办法改变上面的查询?有人有更好的解决方案吗?

  • 我遇到了几个第一个和第二个查询,但它们有同样的问题 - 例如这个解决方案:Finding the highest n values of each group in MySQL 。它不会在同一行中提供第一个和第二个,但主要问题是它只提供了第一个。

谢谢

最佳答案

花了很多时间,终于找到了解决上述问题的方法。请尝试一下:

    select 1st.status as Status,
       SUBSTRING_INDEX(1st.id,'/',1) as 1stID,
       1st.value as 1stValue,
       (case when locate('/',1st.id) > 0 then SUBSTRING_INDEX(1st.id,'/',-1)
             else 2nd.id 
        end) as 2ndID,
        (case when locate('/',1st.id) > 0 then 1st.value
             else 2nd.value 
        end) as 2ndValue
        from
(
(select status, SUBSTRING_INDEX(Group_concat(id separator '/'),'/',2) as id,value
from t1
where (status,value) in (select status,value
from t1
group by status
having max(value))
group by status) 1st

inner join

(select status,id,value
from t1
where (status,value) not in (select status,value
from t1
group by status
having max(value))
group by status,value
order by status,value desc) 2nd
on 1st.status = 2nd.status)
group by 1st.status;

只需将 t1 替换为您的表名,它就会像一个魅力一样工作。

Click here for Updated Demo

如果您有任何疑问,请随时询问。

希望对你有帮助!

关于mysql - 如果值相似,则获取第一个和第二个最高值行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46959101/

相关文章:

mysql - 从包含零的行中获取最大值,负数

C 扩展 : <? 和 >?运营商

asp.net - C# - 从列表中计算最小日期/最大日期

c - 4 功能找到最低/最高位置和值(value)

python - 对列表列表中的元素求和并在 Python 中找到最大值

PHP函数看不到mysqli连接

PHP num_rows 工作但显示错误

php - 如何使用连接和求和构建 Laravel 查询?

mysql - 将DAO QueryDef保存到临时查询并将结果输出到Excel

php - 密码重置后端功能