Генерация серии целых чисел на основе состояния другого столбца в Postgres - PullRequest
0 голосов
/ 09 мая 2019

У меня есть следующие данные

create table test.my_table
(
  date                    date,
  daily_cumulative_precip real
);


INSERT INTO test.my_table (date, daily_cumulative_precip) VALUES ('2016-07-11', 0.508);
INSERT INTO test.my_table (date, daily_cumulative_precip) VALUES ('2016-07-12', 0);
INSERT INTO test.my_table (date, daily_cumulative_precip) VALUES ('2016-07-13', 0);
INSERT INTO test.my_table (date, daily_cumulative_precip) VALUES ('2016-07-14', 2.032);
INSERT INTO test.my_table (date, daily_cumulative_precip) VALUES ('2016-07-15', 0);
INSERT INTO test.my_table (date, daily_cumulative_precip) VALUES ('2016-07-16', 0);
INSERT INTO test.my_table (date, daily_cumulative_precip) VALUES ('2016-07-17', 21.842);
INSERT INTO test.my_table (date, daily_cumulative_precip) VALUES ('2016-07-18', 0);
INSERT INTO test.my_table (date, daily_cumulative_precip) VALUES ('2016-07-19', 0);
INSERT INTO test.my_table (date, daily_cumulative_precip) VALUES ('2016-07-20', 0);

Я хотел бы создать и назначить значения в новом столбце с именем «delta» на основе daily_cumulative_precip.Я хотел бы иметь delta = 0, когда daily_cumulative_precip > 0, delta = 1, когда daily_cumulative_precip = 0 в этот день и предыдущий день, delta = 2, когда daily_cumulative_precip = 0 в этот день и предыдущие 1 дни, и delta = 3, когда daily_cumulative_precip = 0 в этот день и в предыдущие 2 дня.Для этого конкретного набора данных delta должно быть

0, 1, 2, 0, 1, 2, 0, 1, 2, 3

У меня есть следующее, но оно не дает желаемого результата

SELECT *,
      CASE
        WHEN daily_cumulative_precip > 0 THEN 0
        --ELSE date - first_value(date) OVER (ORDER BY date)
          ELSE date - lag(date) OVER (ORDER BY date)
          END AS delta
FROM "test".my_table
ORDER BY date;

Я очень ценю вашу помощь.

Ответы [ 2 ]

4 голосов
/ 09 мая 2019

Для ваших конкретных данных, следующие работы:

select t.*,
       (date - max(date) filter (where daily_cumulative_precip > 0) over (order by date))
from my_table t
order by date;

Получает самую последнюю дату, когда значение больше 0.

Предполагается, что первый день имеет значение больше 0. Если это не всегда так, то:

select t.*,
       (date -
        coalesce(max(date) filter (where daily_cumulative_precip > 0) over (order by date),
                 min(date) over (order by date)
                )
       ) as seqnum
from my_table t
order by date;

Здесь - это дБ <> скрипка.

2 голосов
/ 09 мая 2019

Вот одно из возможных решений.Идея состоит в том, чтобы сначала сгенерировать значение, которое разделит ваши записи на отдельные группы, затем вы можете вычислить дельту для каждой группы.

with partitions as (
select date
     , daily_cumulative_precip
     , sum(case when daily_cumulative_precip <> 0 then 1 else 0 end)
       over (order by date) grp
  from my_table
)
select date
     , daily_cumulative_precip
     , row_number() over (partition by grp order by date) - 1 delta
  from partitions;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...