簡體   English   中英

如何使用Oracle SQL查找連續第二高的值?

[英]How to find the 2nd highest value in a row with Oracle SQL?

我有一排這樣的數據庫:

1|abc|10|30|12

最大值是30,第二高是12。如何獲取表中每一行的第二個值?

這將適用於任意數量的列,只需確保將它們添加到以下查詢中標記為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

不管有多少列,都可以代替......

有多種方法可以實現這一目標。 嘗試這個例子:

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

您基本上從查詢中排除了最高編號,然后從其余查詢中選擇最高編號。

假設值都不同:

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;

如果可以將所有列連接為以逗號分隔的列表,則可以執行以下操作(假設您正在尋找第二高的數值 ):

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;

上面的代碼將返回給定的一組“鍵”列值的第二高值,以及在其中找到該值的列的位置。 我使用串聯和CONNECT BY取消透視表。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM