6

我需要一个 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

4

3 回答 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 对模式的提示!)。上述解决方案将在每一行中找到第二大的列值,即使最大的列值出现不止一次。

于 2013-01-09T11:21:38.363 回答
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

结果将显示:

| ID |  COL | VALUE |
---------------------
|  1 | col3 |     9 |
|  2 | col2 |    14 |
于 2013-01-09T11:21:18.100 回答
0
SELECT MAX(col) FROM table WHERE col NOT IN (SELECT MAX(col) FROM table);

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

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

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

于 2013-01-09T11:18:25.737 回答