Oracle запрос с разными датами

Я должен написать этот запрос, и он немного сложен. Я надеюсь, что кто-то может помочь, так как я получил большую помощь отсюда раньше.

Скажем, у меня есть портфель клиентов. И список тикеров компании, и дата покупки тикера. Мой список выглядит примерно так:

CYSL  1/16/2017
MCIG  4/1/2016
MSRT  9/13/2016
NTFU  1/16/2017
QNTM  10/30/2014
SIGWX 6/28/2014
TRMCX 6/25/2014
TRT2  4/19/2016

Теперь, чтобы я мог вычислить некоторую производительность с начала года, мне нужно применить следующую логику:

Если дата покупки> 01.01.2017, я буду использовать цену закрытия тикера, когда он был куплен. Если дата покупки < 01.01.2017. Я буду использовать цену закрытия тикера <= 31.12.2016.

Здесь задействованы 2 таблицы: 1) Таблица портфелей 2) История цен

Я получил это далеко:

SELECT ticker, MIN(transaction_date) KEEP (DENSE_RANK FIRST ORDER BY transaction_date) transaction_date 
FROM customer_portfolios
WHERE portfolio_id = 954118
GROUP BY ticker;

Это дает мне список выше. Теперь я заблудился о том, как объединить это с логикой выше, чтобы получить правильную дату и пойти по правильной цене.

Я надеюсь, что объясняю это правильно.

И помощь будет отличной, и я могу объяснить больше, если она поможет тебе, помоги мне.

Спасибо.

3 ответа

Использование GREATEST чтобы получить дату в любом 2016-12-31 или более позднюю дату транзакции, а затем просто присоединитесь к таблице истории цен:

SELECT cp.ticker,
       cp.transaction_date,
       h.close_price
FROM   (
  SELECT ticker,
         GREATEST(
           DATE '2016-12-31',
           MIN(transaction_date) KEEP (
             DENSE_RANK FIRST
             ORDER BY transaction_date
           )
         ) AS transaction_date 
  FROM customer_portfolios
  WHERE portfolio_id = 954118
  GROUP BY ticker
) cp
INNER JOIN price_history h
ON (   cp.ticker = h.ticker
   AND cp.transaction_date BETWEEN h.start_date AND h.end_date )

или если в истории цен есть строка в день (а не предполагаемый диапазон в запросе выше), то замените последнюю строку на:

   AND cp.transaction_date = h.price_date )

Возможно, я что-то здесь упускаю, но без каких-либо реальных образцов данных, это лучшее, что я могу придумать. Ниже приведены таблица ddl's, вставки и запросы и изображение результатов.

  CREATE TABLE PRICE_HISTORY 
   (    PRICE_DATE DATE, 
    TICKER VARCHAR2(20 BYTE), 
    OPEN_PRICE NUMBER, 
    CLOSE_PRICE NUMBER
   )

 CREATE TABLE PORTFOLIO_TABLE 
   (    TICKER VARCHAR2(20 BYTE), 
    TICKER_DATE VARCHAR2(20 BYTE), 
    CUSTOMER VARCHAR2(20 BYTE)
   ) 

Insert into PORTFOLIO_TABLE (TICKER,TICKER_DATE,CUSTOMER) values ('CYSL','1/16/2018','1');
Insert into PORTFOLIO_TABLE (TICKER,TICKER_DATE,CUSTOMER) values ('MCIG','04/1/2016','2');
Insert into PORTFOLIO_TABLE (TICKER,TICKER_DATE,CUSTOMER) values ('MSRT','09/13/2016','3');
Insert into PORTFOLIO_TABLE (TICKER,TICKER_DATE,CUSTOMER) values ('NTFU','01/16/2017','4');


Insert into PRICE_HISTORY (PRICE_DATE,TICKER,OPEN_PRICE,CLOSE_PRICE) values (to_date('27-MAR-2017 20:27:12','DD-MON-RRRR HH24:MI:SS'),'CYSL',1,2);
Insert into PRICE_HISTORY (PRICE_DATE,TICKER,OPEN_PRICE,CLOSE_PRICE) values (to_date('16-JUN-1997 20:27:33','DD-MON-RRRR HH24:MI:SS'),'MCIG',1,2);
Insert into PRICE_HISTORY (PRICE_DATE,TICKER,OPEN_PRICE,CLOSE_PRICE) values (to_date('31-MAY-2011 20:27:45','DD-MON-RRRR HH24:MI:SS'),'MSRT',5,8);
Insert into PRICE_HISTORY (PRICE_DATE,TICKER,OPEN_PRICE,CLOSE_PRICE) values (to_date('25-JAN-2021 20:27:55','DD-MON-RRRR HH24:MI:SS'),'NTFU',7,6);


WITH portfolio AS
  ( SELECT TICKER , TICKER_DATE, CUSTOMER FROM PORTFOLIO_TABLE
  )
SELECT
  CASE
    WHEN PRICE_DATE > '01-JAN-17'
    THEN CLOSE_PRICE
    ELSE OPEN_PRICE
  END AS AMOUNT,
  PRICE_DATE,
  P.TICKER,
  OPEN_PRICE,
  CLOSE_PRICE
FROM PRICE_HISTORY H,
  PORTFOLIO P
WHERE H.TICKER = P.TICKER;

Конечная цель этого запроса - получить СУММУ портфеля клиентов по его покупкам.

Эта часть работает отлично!

ВЫБЕРИТЕ m_ticker, GREATEST(ДАТА '2016-12-31', МИН. (Транзакция_дата) СОХРАНИТЬ ( DENSE_RANK ПЕРВЫЙ ЗАКАЗ ПО транзакции_дата)) КАК транзакция_дата ОТ customer_portfolio_history WHERE portfolio_id = 954118 GROUP BY m_ticker;

Дает мне данные, которые мне нужны:

CYSL 16.01.2017
MCIG 31.12.2016
MSRT 31/12/2016
НТФУ 16.01.2017
QNTM 31.12.2016
SIGWX 31.12.2016
TRMCX 31.12.2016
TRT2 31.12.2016

Теперь становится сложнее. С результатами, приведенными выше, мне нужно перейти в PRICE_HISTORY и найти цену, которая находится на или ближе к (ранее) этой дате.

Таким образом, если нет записи на 31.12.2016 (возможно, рынок был закрыт), попробуйте 12/30, 12/29 и т. Д. То же самое для 16.01.2017. Если нет записи, попробуйте 1/15, затем 1/14....

После этого я могу взять общее количество # акций из таблицы PORTFOLIO для этого клиента / портфеля / тикера и умножить его на цену, которую я получу за найденный день..... и получим значение.

Довольно сумасшедший, я знаю.

Другие вопросы по тегам