Oracle - 查找NEXT最大数字

时间:2017-03-24 18:57:13

标签: oracle sorting next highest

说我有一份日期清单&价格:

20170322    109.89
20170321    107.02
20170320    109.25
20170317    108.44
20170316    108.53
20170315    107.94
20170314    106.83
20170313    110.02
20170310    107.31
20170309    107.54
20170308    107.67
20170307    108.98

我需要的是,从最近的日期:20170322(109.89),第一个日期/价格值高于原始值,即20170313(110.02)。请注意,这些是DESC的日期顺序

一直都在这一天。

2 个答案:

答案 0 :(得分:0)

假设这些列被称为DT和PRICE,并且假设只有一个“东西”,你监视它的价格(否则你需要一个GROUP BY子句):

select min(dt) as dt, min(price) keep (dense_rank first order by dt) as price
from   your_table
where  price > ( select min(price) keep (dense_rank first order by dt)
                 from   your_table
               )

https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions056.htm

答案 1 :(得分:0)

使用MATCH_RECOGNIZE子句的解决方案(需要Oracle 12及更高版本)。

我在WITH子句中创建了测试数据。这不是解决方案的一部分; SQL查询在WITH子句之后开始,位于SELECT TICKER, ....

PATTERN中不情愿匹配中的问号使JDBC驱动程序跳闸,因此无法从SQL Developer运行此查询;它需要在SQL * Plus或类似的前端运行。 (解决方法是将b*?更改为b*并添加到DEFINE子句:b as b.price <= a.price。)

为了说明MATCH_RECOGNIZE的更多灵活性,我假设可能有几个&#34;代码&#34;,每个都有它的开始日期(最早的价格日期),并且查询查找每个股票代码首次出现高于原价的价格。

with
     test_data ( ticker, dt, price ) as (
       select 'XYZ', to_date('20170322', 'yyyymmdd'), 109.89 from dual union all
       select 'XYZ', to_date('20170321', 'yyyymmdd'), 107.02 from dual union all
       select 'XYZ', to_date('20170320', 'yyyymmdd'), 109.25 from dual union all
       select 'XYZ', to_date('20170317', 'yyyymmdd'), 108.44 from dual union all
       select 'XYZ', to_date('20170316', 'yyyymmdd'), 108.53 from dual union all
       select 'XYZ', to_date('20170315', 'yyyymmdd'), 107.94 from dual union all
       select 'XYZ', to_date('20170314', 'yyyymmdd'), 106.83 from dual union all
       select 'XYZ', to_date('20170313', 'yyyymmdd'), 110.02 from dual union all
       select 'XYZ', to_date('20170310', 'yyyymmdd'), 107.31 from dual union all
       select 'XYZ', to_date('20170309', 'yyyymmdd'), 107.54 from dual union all
       select 'XYZ', to_date('20170308', 'yyyymmdd'), 107.67 from dual union all
       select 'XYZ', to_date('20170307', 'yyyymmdd'), 108.98 from dual
     )
select ticker, dt, price
from   test_data
match_recognize (
  partition by ticker
  order     by dt
  measures  c.dt as dt, c.price as price
  one row per match
  pattern   ( ^ a b*? c )
  define    c as c.price > a.price
)
;

TICKER  DT            PRICE
------  ----------  -------
XYZ     2017-03-13   110.02

1 row selected.
相关问题