Как рассчитать просадку в Mysql с помощью оконных функций? - PullRequest
0 голосов
/ 13 апреля 2020

У меня есть эта схема:

CREATE TABLE `test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `amount` int(11) DEFAULT NULL,
  `group_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
);

, и я заполнил эту таблицу следующими данными:

insert into test (amount, group_id) values
(1,1), (3,1), (-4,1), (-2,1), (5,1), (10,1), (18,1), (-3,1), 
(-5,1), (-7,1), (12,1), (-9,1), (6,1), (0,1), (185,2), (-150,2) 

Таблица:

# id, amount, group_id
1, 1, 1
2, 3, 1
3, -4, 1
4, -2, 1
5, 5, 1
6, 10, 1
7, 18, 1
8, -3, 1
9, -5, 1
10, -7, 1
11, 12, 1
12, -9, 1
13, 6, 1
14, 0, 1
15, 185, 2
16, -150, 2

Это запрос, который я сейчас использую:

SELECT 
    t1.id, 
    t1.amount, 
    t1.cumsum, 
    (MAX(t1.cumsum) OVER (ORDER BY id RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) - t1.cumsum) as drawdown    
FROM 
(
    SELECT 
        id,
        amount,
        group_id,
        SUM(amount) OVER (ORDER BY id RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as cumsum        
    FROM 
        test
) as t1
order by drawdown desc

запрос возвращает этот вывод:

id, amount, cumsum, drawdown
10  -7  16  15
12  -9  19  12
9   -5  23  8
4   -2  -2  6
14  0   25  6
13  6   25  6
3   -4  0   4
8   -3  28  3
11  12  28  3
5   5   3   1
16  150 360 0
2   3   4   0
7   18  31  0
15  185 210 0
1   1   1   0
6   10  13  0

Просто быстрое уточнение: с термином «просадка» (в данном случае) я имею в виду разницу от максимального значения суммы (поля) И простого значения (совокупной суммы).

Я не имею в виду какое-либо конкретное определение торговли, мне просто нужно различие между самым большим выбором и низкий. (очевидно, самый высокий пик должен произойти до самого низкого = нисходящего тренда).

ОК, моя проблема в том, что мне нужно сгруппировать по полю group_id, если я добавлю предложение group by в запросе все * Функция 1035 * испортится.

РЕЗУЛЬТАТ РЕЗУЛЬТАТА:

Мне нужно получить список, сгруппированный по полю group_id, который показывает максимальную просадку для каждой группы .

Редактировать: (@Akina)

group_id, drawdown
1    15
2    150
...