如何使用Oracle SQL连续找到第二高的值?

时间:2015-03-10 02:48:42

标签: sql oracle

我有一行数据库如下:

1|abc|10|30|12

最大值是30,第二个最高值是12.如何获得表格中每行的第二个值?

4 个答案:

答案 0 :(得分:2)

这适用于任意数量的列,只需确保将它们添加到我的查询中标有merge_col的连接列表中:

select col1, col2, col3, col4, col5, second_highest
  from (select x.*,
               regexp_substr(merge_col, '[^|]+', 1, levels.column_value) as second_highest,
               row_number() over(partition by x.col1 order by to_number(regexp_substr(merge_col, '[^|]+', 1, levels.column_value)) desc) as rn
          from (select t.*, col3 || '|' || col4 || '|' || col5 as merge_col
                  from tbl t) x,
               table(cast(multiset
                          (select level
                             from dual
                           connect by level <=
                                      length(regexp_replace(merge_col,
                                                            '[^|]+')) + 1) as
                          sys.OdciNumberList)) levels)
 where rn = 2

小提琴测试: http://sqlfiddle.com/#!4/b446f/2/0

换句话说,对于其他列,请更改:

col3 || '|' || col4 || '|' || col5 as merge_col

为:

col3 || '|' || col4 || '|' || col5 || '|' || col6 .........  as merge_col

但是有很多列代替......

答案 1 :(得分:1)

有不同的方法可以实现这一目标。试试这个:例如:

SELECT MAX('column_name') FROM 'table_name'
WHERE 'column_name' NOT IN (SELECT MAX('column_name') FROM 'table_name' )

您基本上从查询中排除了最高的数字,然后选择其余的最高数字。

答案 2 :(得分:1)

假设值都不同:

select t.*,
       (case when col1 <> greatest(col1, col2, col3) and
                  col1 <> least(col1, col2, col3)
             then col1
             when col2 <> greatest(col1, col2, col3) and
                  col2 <> least(col1, col2, col3)
             then col2
             else col3
        end) as secondgreatest
from table t;

答案 3 :(得分:0)

如果您可以将所有列连接为以逗号分隔的列表,那么您可以执行以下操作(假设您正在寻找第二高的数字值):

WITH d1 AS (
    SELECT keycolumn1, keycolumn2, col1 || ',' || col2 || ',' || ... || ',' || colx AS other_columns
      FROM mytable
), d2 AS (
    SELECT keycolumn1, keycolumn2, LEVEL AS pos
         , TO_NUMBER(REGEXP_SUBSTR(other_columns, '[^,]+', 1, LEVEL)) AS cvalue
      FROM d1
   CONNECT BY REGEXP_SUBSTR(other_columns, '[^,]+', 1, LEVEL) IS NOT NULL
       AND PRIOR keycolumn1 = keycolumn1
       AND PRIOR keycolumn2 = keycolumn2
       AND PRIOR DBMS_RANDOM.VALUE IS NOT NULL
)
SELECT keycolumn1, keycolumn2, pos, cvalue FROM (
    SELECT keycolumn1, keycolumn2, pos, cvalue
         , ROW_NUMBER() OVER ( PARTITION BY keycolumn1, keycolumn2 ORDER BY cvalue DESC ) AS rn
      FROM d2
) WHERE rn = 2;

以上将返回给定的一组&#34;键&#34;的第二高值。列值以及找到该值的列的位置。我使用连接和CONNECT BY来解开表格。