Get the second highest max for each value on Oracle

Viewed 171

I want to get the second highest max using PL/SQL (Oracle).

I have a table that looks like this:

CLIENT | ORDER_DATE
1      | 14/09/2018
1      | 01/02/2019
2      | 13/12/2019
2      | 01/01/2020
2      | 15/12/2019

I want to get a table with the max(ORDER_DATE) and the 2nd highest max(ORDER_DATE) for each client:

CLIENT | MAX(ORDER_DATE) | 2nd highest max(ORDER_DATE)
1      | 01/02/2019      | 14/09/2018
2      | 01/01/2020      | 15/12/2019

I have tried using rank, but got only one row (one random client):

select *
  from (select CLIENT,
               max(ORDER_DATE),
               row_number() over (order by max(ORDER_DATE) desc) as rk
          from order_table
         group by CLIENT) t
 where rk = 2
3 Answers

You need conditional aggregation after appyling analytic function such as ROW_NUMBER() :

WITH t2 AS
(
  SELECT client,order_date,
         ROW_NUMBER() OVER (PARTITION BY client ORDER BY order_date DESC) as rk
   FROM order_table
)
SELECT client, 
       MAX(CASE WHEN rk=1 THEN order_date END) AS "max order date",
       MAX(CASE WHEN rk=2 THEN order_date END) AS "2nd highest max ord.date"
  FROM t2
 GROUP BY client

Demo

You can try the below - use partition by client in over() clause

select client,max_date,order as seconf_highest_date from
(
select *,max(ORDER_DATE) over(partition by client order by ORDER_DATE desc) as max_date,
         row_number() over (partition by client order by ORDER_DATE desc) as rk
   from order_table
)A where rk=2

You can do this using analytic functions as well:

select distinct client, 
       max(date) over (partition by client),
       nth_value(date, 2) over (partition by client order by date desc)
from order_date;

Happily, Oracle supports nth_value() as an analytic function. Sadly, Oracle does not offer the same functionality as a simpler aggregation function.

Related