使用 MATCH_RECOGNIZE 子句的解决方案(需要 Oracle 12 及更高版本)。
我在 WITH 子句中创建了测试数据。这不是解决方案的一部分;SQL 查询在 WITH 子句之后开始,在SELECT TICKER, ....
PATTERN 中不情愿匹配中的问号会使 JDBC 驱动程序跳闸,因此无法从 SQL Developer 运行此查询;它需要在 SQL*Plus 或类似的前端中运行。(解决方法是更改并添加到 DEFINE 子句:b*?
。)b*
b as b.price <= a.price
为了说明 的更多灵活性MATCH_RECOGNIZE
,我假设可能有几个“代码”,每个都有其开始日期(带有价格的最早日期),并且查询查找价格高于原始价格的第一次出现,每个代码.
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.