#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
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. Спасибо за ваш ответ; однако, похоже, выполнение этого запроса занимает целую вечность; Я посмотрю на результаты, когда они появятся…