Попытка получить положительную или отрицательную разницу в окне в запросе postgresql

#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  |
  

Просмотр на скрипке DB