Min(), Max() в подмножестве дат

#oracle #range #max #min

#Oracle #диапазон #макс #min

Вопрос:

Не уверен, подходит ли заголовок, но вот моя проблема: у меня есть следующая таблица:

 create table OpenTrades(
AccountNumber   number,
SnapshotTime    date,
Ticket          number,
OpenTime        date,
TradeType       varchar2(4),
TradeSize       number,
TradeItem       char(6),
OpenPrice       number,
CurrentAsk      number,
CurrentBid      number,
TradeSL         number,
TradeTP         number,
TradeSwap       number,
TradeProfit     number  
);
alter table OpenTrades add constraint OpenTrades_PK Primary Key (AccountNumber, SnapshotTime, Ticket) using index tablespace MyNNIdx;
  

Для каждого (SnapshotTime, учетная запись) я хочу выбрать min (OpenPrice), max (OpenPrice) таким образом, чтобы результат min и max относились только к прошлому, относительно SnapshotTime.
Например, для любой возможной пары (учетная запись, tradeitem) у меня может быть 10 записей, скажем, с Snapshottime = 10 июня и openprice между 0.9 и 2.0, а также еще 10 записей с SnapshotTime = 11 июня и openprice между 1.0 и 2.1, а также еще 10 записей сSnapshotTime = 12 июня, а openprice — от 0,7 до 1,9.
В таком сценарии искомый запрос должен возвращать что-то вроде этого:

 AccountNumber  SnapshotTime  MyMin   MyMax
-------------  ------------  -----   -----
1234567        10-jun        0.9      2.0
1234567        11-jun        0.9      2.1
1234567        12-jun        0.7      2.1
  

Я уже пробовал это, но он возвращает только min () и max() в течение одного и того же времени моментального снимка:

 select accountnumber, snapshottime, tradeitem, min(openprice), max(openprice) 
from opentrades 
group by accountnumber, snapshottime, tradeitem
  

Любая помощь будет оценена.

Ответ №1:

Для этого можно использовать аналитические версии min() и max() , а также оконные предложения:

 select distinct accountnumber, snapshottime, tradeitem,
  min(openprice) over (partition by accountnumber, tradeitem
    order by snapshottime, openprice
    rows between unbounded preceding and current row) as min_openprice,
  max(openprice) over (partition by accountnumber, tradeitem
    order by snapshottime, openprice desc
    rows between unbounded preceding and current row) as max_openprice
from opentrades
order by accountnumber, snapshottime, tradeitem;

ACCOUNTNUMBER SNAPSHOTTIME TRADEITEM MIN_OPENPRICE MAX_OPENPRICE
------------- ------------ --------- ------------- -------------
      1234567 10-JUN-14    X                    .9             2 
      1234567 11-JUN-14    X                    .9           2.1 
      1234567 12-JUN-14    X                    .7           2.1 
  

Скрипка SQL.

partition by Вычисляет значение для текущего accountnumber и tradeitem в подмножестве строк на основе rows between предложения; order by это означает, что он просматривает только строки в любом предыдущем снимке и вплоть до самого низкого (для min ) или самого высокого (для max , из-за desc ) в текущем снимке, при вычислении соответствующего минимального / максимального значения.для каждой строки.

Результат анализа вычисляется для каждой строки. Если вы запустите его без distinct , то увидите все ваши базовые данные плюс те же минимальные / максимальные значения для каждого снимка (скрипки). Поскольку вам не нужны какие-либо изменяющиеся данные, вы можете подавить дублирование с distinct помощью, или, сделав его запросом с a row_number() , который затем фильтруется, и т.д.

Комментарии:

1. Большое вам спасибо. Похоже, это действительно ответило на мои потребности. Я определенно должен лучше ознакомиться с аналитическими функциями Oracle…

Ответ №2:

Это отвечает на вашу проблему?

 select ot1.accountnumber, ot1.snapshottime, ot1.tradeitem,
       min(ot2.openprice), max(ot2.openprice)
from opentrades ot1, opentrades ot2
where ot2.accountnumber = ot1.accountnumber
  and ot2.tradeitem = ot1.tradeitem
  and ot2.snapshottime <= ot1.snapshottime
group by ot1.accountnumber, ot1.snapshottime, ot1.tradeitem
  

Комментарии:

1. Спасибо за ваш ответ; однако, похоже, выполнение этого запроса занимает целую вечность; Я посмотрю на результаты, когда они появятся…