我需要一个 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 中会变得非常冗长
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 对模式的提示!)。上述解决方案将在每一行中找到第二大的列值,即使最大的列值出现不止一次。
您可以通过取消透视数据然后将行号应用于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
结果将显示:
| ID | COL | VALUE |
---------------------
| 1 | col3 | 9 |
| 2 | col2 | 14 |
SELECT MAX(col) FROM table WHERE col NOT IN (SELECT MAX(col) FROM table);
这为您提供了特定列中的第二大整数值。
编辑:然后在执行此操作之前将行与列交换。但如果这些列是动态的,那可能会非常棘手。
最好/最简单的方法是直接使用客户端语言而不是 SQL 来执行此特定操作。如果不可能,请检查:Transpose rows and columns without aggregate