Накопленная сумма на основе условия в другом столбце

Я хотел бы создать представление на основе данных в следующей структуре:

CREATE TABLE my_table (
  date date,
  daily_cumulative_precip float4
);

INSERT INTO my_table (date, daily_cumulative_precip)
VALUES
  ('2016-07-28', 3.048)
, ('2016-08-04', 2.286)
, ('2016-08-11', 5.334)
, ('2016-08-12', 0.254)
, ('2016-08-13', 2.794)
, ('2016-08-14', 2.286)
, ('2016-08-15', 3.302)
, ('2016-08-17', 3.81)
, ('2016-08-19', 15.746)
, ('2016-08-20', 46.739998);

Я хотел бы накапливать осадки только за последовательные дни.

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

введите здесь описание изображения

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

Как я мог это решить?


person achimneyswallow    schedule 08.05.2019    source источник
comment
Результат должен действительно соответствовать заданному тестовому примеру.   -  person Erwin Brandstetter    schedule 08.05.2019


Ответы (2)


SELECT date
     , dense_rank() OVER (ORDER BY grp) AS consecutive_group_nr  -- optional
     , daily_cumulative_precip
     , sum(daily_cumulative_precip) OVER (PARTITION BY grp ORDER BY date) AS cum_precipitation_mm
FROM  (
   SELECT date, t.daily_cumulative_precip
        , row_number() OVER (ORDER BY date) - t.rn AS grp
   FROM  (
      SELECT generate_series (min(date), max(date), interval '1 day')::date AS date
      FROM   my_table
      ) d
   LEFT   JOIN (SELECT *, row_number() OVER (ORDER BY date) AS rn FROM my_table) t USING (date)
   ) x
WHERE  daily_cumulative_precip > 0
ORDER  BY date;

db‹>скрипка здесь

Возвращает все дождливые дни с кумулятивными суммами за последовательные дни (и текущий номер группы).

Основы:

person Erwin Brandstetter    schedule 08.05.2019
comment
Вы видели скрипку, демонстрирующую, что она работает? Отсутствует важная информация? Нравится ваша версия Postgres? - person Erwin Brandstetter; 08.05.2019

Вот способ расчета совокупного количества осадков без явного перечисления всех дат:

SELECT date, daily_cumulative_precip, sum(daily_cumulative_precip) over (partition by group_num order by date) as cum_precip
FROM
    (SELECT date, daily_cumulative_precip, sum(start_group) over (order by date) as group_num
    FROM
        (SELECT date, daily_cumulative_precip, CASE WHEN (date != prev_date + 1) THEN 1 ELSE 0 END as start_group
        FROM
            (SELECT date, daily_cumulative_precip, lag(date, 1, '-infinity'::date) over (order by date) as prev_date
            FROM my_table) t1) t2) t3

урожаи

|       date | daily_cumulative_precip | cum_precip |
|------------+-------------------------+------------|
| 2016-07-28 |                   3.048 |      3.048 |
| 2016-08-04 |                   2.286 |      2.286 |
| 2016-08-11 |                   5.334 |      5.334 |
| 2016-08-12 |                   0.254 |      5.588 |
| 2016-08-13 |                   2.794 |      8.382 |
| 2016-08-14 |                   2.286 |     10.668 |
| 2016-08-15 |                   3.302 |      13.97 |
| 2016-08-17 |                    3.81 |       3.81 |
| 2016-08-19 |                  15.746 |     15.746 |
| 2016-08-20 |                   46.74 |     62.486 |
person unutbu    schedule 08.05.2019