У меня есть следующее:
CREATE TABLE #MASTER_POSANDTRANS (ID CHAR(30),
QUANTITY INT,
START_OR_TRADE_DATE DATE)
VALUES
('APPLES ','150000','20150501'), ('PEARS','220000','20150501'),
('APPLES ','-75000','20150506'), ('APPLES ','-65000','20150508'),
('APPLES ','10000','20150516'), ('APPLES ','-20000','20150519'
('PEARS','-110000','20150506'), ('PEARS','-100000','20150519')
Я хочу иметь возможность сказать: «Хорошо, вначале у меня было 150 000 яблок, поэтому моя общая позиция по яблокам была ДЛИННОЙ».
Вот как я сейчас решаю эту маленькую головоломку:
SELECT
MPT.ID,
MPT.QUANTITY,
MPT.START_OR_TRADE_DATE,
APPLY_RES.QUANTITY as 'FIRST AVAILABLE QUANTITY',
CASE
WHEN APPLY_RES.QUANTITY > 0
THEN 'LONG'
ELSE 'SHORT'
END as 'L/S Indicator'
FROM
#MASTER_POSANDTRANS as MPT
CROSS APPLY
(SELECT TOP 1
MPT_APPLY.QUANTITY
FROM
#MASTER_POSANDTRANS as MPT_APPLY
WHERE
MPT_APPLY.ID = MPT.ID) APPLY_RES
Представленная таблица представляет собой упрощенный результат нескольких запросов и объединений, которые выдают около 387 строк примерно за 3 секунды. Однако, когда я пытаюсь применить свое решение к этому результату из 387 строк, мой запрос возвращает правильный результат, но занимает 21 секунду вместо 3.
Есть предложения по улучшению?
Еще немного к головоломке:
Первая доступная «транзакция» решает, буду ли я играть в длинную или короткую позицию.
Другая, более сложная проблема (для тех, кто любит головоломки) состоит в том, чтобы взять средневзвешенный холдинг, чтобы решить, был ли я в длинной или короткой позиции в течение периода. Например, представьте, что после последней сделки с яблоками 19-го числа, когда у меня осталось 0 яблок, я продал еще 1 миллион яблок. Это означало бы, что с 19 по 31 мая у меня не было 1 миллиона. (31-19) * -1 000 000 ‹ (19-1)*(Среднее количество проданных/купленных яблок в течение месяца), следовательно, мое владение яблоками в этом месяце можно считать коротким. Если бы в какой-то момент они уравновесились, я бы взял значение в точке 1.