#sql #database #postgresql
#sql #База данных #postgresql
Вопрос:
У меня есть таблица, daily
, следующим образом:
|date|high|low|
Я пытаюсь вернуть максимальную положительную или отрицательную разницу для каждого N-дневного окна данных. Например, следующий запрос очень приближает меня к 5-дневному окну:
SELECT date, high, low, (high - low) AS diff
FROM (
SELECT dd.date AS date,
MAX(dd.high)
OVER(ORDER BY dd.date ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) AS high,
MIN(dd.low)
OVER(ORDER BY dd.date ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) AS low
FROM daily dd
) AS win
ORDER BY date
Однако этот запрос неверен, потому что результат всегда будет положительным. Если максимум произошел до минимума, результат должен быть отрицательным. Есть ли способ выполнить это с помощью запроса?
РЕДАКТИРОВАТЬ: добавление примеров и ожидаемого результата
EDIT2: изменено с лучшим примером
|date |high|low|
|01-01-2001|20 |10 |
|01-02-2001|30 |20 |
|01-03-2001|40 |30 |
|01-04-2001|30 |25 |
|01-05-2001|35 |25 |
Результат за 5-дневный период должен быть:
|date |high|low|diff|
|01-01-2001|20 |10 |10 |
|01-02-2001|30 |10 |20 |
|01-03-2001|40 |10 |30 |
|01-04-2001|40 |10 |30 |
|01-05-2001|40 |10 |30 |
Результат за 3-дневный период должен быть:
|01-01-2001|20 |10 |10 |
|01-02-2001|30 |10 |20 |
|01-03-2001|40 |10 |10 |
|01-04-2001|40 |20 |20 |
|01-05-2001|40 |25 |-15 |
Комментарии:
1. можете ли вы показать некоторые примеры данных и ожидаемый результат?
2. Добавлены примеры данных с ожидаемыми результатами.
3. Как насчет того, что две строки имеют одинаковое наименьшее или наибольшее значение, но разные даты?
4. @ToBeFrank . , , Ваши образцы данных не очень помогают. Ваш исходный запрос возвращает одно значение на строку. Ваш пример возвращает одну строку на пять значений. Это также не объясняет, что делать, когда максимум и минимум приходятся на одну и ту же дату.
5. Модифицировано лучшим примером
Ответ №1:
Вы можете попробовать использовать подзапрос, чтобы получить наибольшее и наименьшее значение из ежедневной таблицы. затем выполните SELF JOIN
CASE WHEN
CREATE TABLE daily(
date date,
high int,
low int
);
INSERT INTO daily VALUES ('01-01-2001',40 ,30);
INSERT INTO daily VALUES ('01-02-2001',30 ,25);
INSERT INTO daily VALUES ('01-03-2001',35 ,25);
INSERT INTO daily VALUES ('01-04-2001',20 ,10);
INSERT INTO daily VALUES ('01-05-2001',30 ,20);
Запрос # 1
SELECT t1.*,
CASE WHEN highdt.date > lowdt.date
THEN highest - lowest
ELSE lowest - highest
END diff
FROM (
select MAX(date) dates,
MAX(high) highest,
MIN(low) lowest
from daily
) t1
JOIN daily highdt ON t1.highest = highdt.high
JOIN daily lowdt ON t1.lowest = lowdt.low;
| dates | highest | lowest | diff |
| ------------------------ | ------- | ------ | ---- |
| 2001-01-05T00:00:00.000Z | 40 | 10 | -30 |