Как рассчитать среднее значение за каждый месяц с начала года в Presto's SQL (Афина)? - PullRequest
1 голос
/ 21 июня 2020

Ниже приведен пример данных таблицы, которые у меня есть

| date       | value |
| 2020-01-01 |  20   |
| 2020-01-14 |  10   |
| 2020-02-02 |  30   |
| 2020-02-11 |  25   |
| 2020-02-25 |  25   |
| 2020-03-13 |  34   |
| 2020-03-21 |  10   |
| 2020-04-06 |  55   |
| 2020-04-07 |  11   |

Я хотел бы сгенерировать набор результатов, как показано ниже

| date       | value |  average                       |
| 2020-01-01 |  20   |  Jan average                   |
| 2020-01-14 |  10   |  Jan average                   |   
| 2020-02-02 |  30   |  Jan & Feb average             |
| 2020-02-11 |  25   |  Jan & Feb average             |
| 2020-02-25 |  25   |  Jan & Feb average             |
| 2020-03-13 |  34   |  Jan & Feb & Mar average       |
| 2020-03-21 |  10   |  Jan & Feb & Mar average       |
| 2020-04-06 |  55   |  Jan & Feb & Mar & Apr average |
| 2020-04-07 |  11   |  Jan & Feb & Mar & Apr average |

Я пытался использовать оконную функцию OVER () и PARTITION (), но мне удалось получить среднее значение по месяцам, а не по годам.

Любые предложения, пожалуйста.

Спасибо

Ответы [ 4 ]

2 голосов
/ 21 июня 2020

Не уверен, что я понимаю ваш вопрос, но если все, что вам нужно, это скользящее среднее для каждой строки, привязанной к году:

SELECT date, value, (
  SELECT AVG(value)
  FROM data ds
  WHERE ds.date <= d.date AND YEAR(ds.date) = YEAR(d.date)
) average
FROM data d
ORDER BY d.date ASC;

Пример с MySQL (синтаксис для этот запрос c такой же)

Если вы хотите включить в среднее значение более поздние строки того же месяца, используйте WHERE MONTH(ds.date) <= MONTH(d.date).

2 голосов
/ 21 июня 2020

Этот следующий запрос должен дать ваш ожидаемый результат -

Демо здесь

SELECT A.*,
(
    SELECT AVG(Value * 1.00) 
    FROM your_table B 
    WHERE YEAR(B.Date) = YEAR(A.DAte) 
    AND MONTH(B.Date) <= MONTH(A.DAte)
)
FROM your_table A

Этот запрос будет делать ваш результат за год. Но если вы не хотите разделения по ГОДУ, просто удалите фильтр ГОД из подзапроса.

Следующий запрос вернет СРЕДНЕЕ без учета ГОДА, просто СРЕДНЕЕ всех до месяцев -

Здесь демо

SELECT A.*,
(
    SELECT AVG(Value * 1.00) 
    FROM your_table B 
    WHERE B.date <= 
    (
        SELECT MAX(Date) 
        FROM your_table C
        WHERE YEAR(c.Date) = YEAR(A.Date)
        AND MONTH(C.Date) = MONTH(A.Date)
    )
)
FROM your_table A
0 голосов
/ 21 июня 2020
SELECT a.date,
    a.value,
     (Select avg(b.value) from myTable B where b.date < a.date and YEAR(a.date) = YEAR(b.date)) 
From myTable a
0 голосов
/ 21 июня 2020

Я думаю, вы хотите:

select 
    t.*,
    avg(value) over(
        partition by year(date)
        order by month(date)
    ) running_avg
from mytable t

Это помещает каждый год в отдельный раздел, а строки разбивают по месяцам.

...