SQL:从一行的一列中获取至少第三大值

问题描述 投票:6回答:3

我需要一个SQL查询来从一行的一组列中获取第二大值。例如,如果这些是我的表的行:

id | col1 | col2 | col3 | col4 | coln |
1  |   5  |   7  |   9  |  3   |  10  |
2  |   13 |   14 |   2  |  54  |  11  |

对于rowid 1 - 我需要值9,rowid 2 - 我需要值14

mysql sql database
3个回答
5
投票

我担心,如果没有公用表表达式和/或窗口函数,并且不需要编写过程,这在MySQL中会变得非常冗长

SELECT t.id, t.val second_largest
-- unpivot your columns into a table
FROM (
  SELECT id, col1 val FROM my_table UNION ALL
  SELECT id, col2     FROM my_table UNION ALL
  SELECT id, col3     FROM my_table UNION ALL
  SELECT id, col4     FROM my_table UNION ALL
  SELECT id, coln     FROM my_table
) t

-- retain only those records, where there exists exactly one record with a
-- column value greater than any other column value with the same id
WHERE 1 = (
  SELECT COUNT(*) 
  -- Here, use unions to be sure that every value appears exactly once
  FROM (
    SELECT id, col1 val FROM my_table UNION
    SELECT id, col2     FROM my_table UNION
    SELECT id, col3     FROM my_table UNION
    SELECT id, col4     FROM my_table UNION
    SELECT id, coln     FROM my_table
  ) u
  WHERE t.id = u.id
  AND t.val < u.val
)

这是SQLFiddle检查它(感谢bluefeet与模式的单挑!)。即使最大列值出现多次,上述解决方案也会在每一行中找到第二大列值。


3
投票

您可以通过取消数据,然后将行号应用于id组中的每个记录来完成此操作。 unpivot从列布局中获取数据并将其放入行中,以便更容易确定第二个最高值:

select id, col, value
from
(
  -- assign a group row number to each record 
  select *, 
    @row:=(case when @prev=id and @prevvalue<>value then @row else 0 end) + 1 as rownum,
    @prevvalue:=value,
    @prev:=id pid
  from
  (
    -- unpivot the multi columns into row values
    select id, 'col1' col, col1 value
    from yourtable
    union all
    select id, 'col2' col, col2 value
    from yourtable
    union all
    select id, 'col3' col, col3 value
    from yourtable
    union all
    select id, 'col4' col, col4 value
    from yourtable
    union all
    select id, 'coln' col, coln value
    from yourtable
  ) src
  order by id, value desc
) src
-- apply filter looking for the rownumber = 2 which is the second highest based on order
where rownum = 2

SQL Fiddle with Demo

结果将显示:

| ID |  COL | VALUE |
---------------------
|  1 | col3 |     9 |
|  2 | col2 |    14 |

0
投票
SELECT MAX(col) FROM table WHERE col NOT IN (SELECT MAX(col) FROM table);

这为您提供了特定列中的第二大整数值。

编辑:然后在执行此操作之前,只需将行与列交换。但如果列是动态的,那可能会非常棘手。

最好/最简单的方法是使用客户端语言而不是SQL直接用于此特定操作。如果不可能,请检查:Transpose rows and columns without aggregate

© www.soinside.com 2019 - 2024. All rights reserved.