Postgres - создать серию - PullRequest
       33

Postgres - создать серию

0 голосов
/ 16 октября 2019

У меня есть таблица (tb1), содержащая столбец с датой создания (столбец A) и с датой изменения (столбец B).

Я хотел бы получить сводную меру, показывающую, сколько записей было создано за данный интервал и сколько было изменено за тот же интервал.

До сих пор я пробовал следующий код:

Select count(distinct tb.id),dd 
from generate_series ('2015-01-01'::timestamp,'2019-11-01'::timestamp,'1 month'::interval)dd
left join tb on tb.columnA<=dd::date
group by dd

Вывод, который я получаю, в порядке, так как я получаю следующую таблицу

dd/count
2015-01-01/ 2
2015-02-01/ 6
2015-03-01/ 10
2015-04-01/ 22
...

Однако,Мне интересно, как я могу включить информацию из второго столбца (columB), чтобы я увидел, что в 2015-03-01 было создано в общей сложности десять учетных записей, но, например, три из них были изменены.

Нужен ли второй запрос или это можно сделать за то же самое?

Ответы [ 2 ]

0 голосов
/ 16 октября 2019

относительно вашего ответа. Большое спасибо.

Я выполнил боковое соединение.

select gs.dd,
       sum(v.is_create) as create_on_date,
       sum(v.is_update) as update_on_day,
       sum(sum(v.is_create)) over (order by gs.dd) as running_creates,
       sum(sum(v.is_update)) over (order by gs.dd) as running_updates
from generate_series('2015-01-01'::timestamp,'2019-11-01'::timestamp,'1 month'::interval
                    ) gs(dd) left join
     (tb cross join lateral
      (values (tb.creation_date, 0, 1), (tb.modification_date, 1, 0)
      ) v(dte, is_update, is_create)
     )
     on v.dte::date = dd::date
where v.dte is not null
and tb.gather_stats is not false
group by gs.dd
order by gs.dd;

Теперь я получаю следующую таблицу

Снимок экрана с выводом данных

Дата модификации может быть на самом деле null, но, к сожалению,также дата создания может быть null.

Если посмотреть на необработанные данные, например, есть две записи с датой изменения в декабре 2017 года (где дата создания null).

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

0 голосов
/ 16 октября 2019

Используйте lateral join для разворота данных и агрегирования:

select gs.dd,
       sum(v.is_create) as create_on_date,
       sum(v.is_update) as update_on_day,
       sum(sum(v.is_create)) over (order by gs.dd) as running_creates,
       sum(sum(v.is_update)) over (order by gs.dd) as running_updates
from generate_series('2015-01-01'::timestamp,'2019-11-01'::timestamp,'1 month'::interval
                    ) gs(dd) left join
     (tb cross join lateral
      (values (tb.updatedon, 0, 1), (createdon, 1, 0)
      ) v(dte, is_update, is_create)
     )
     on v.dte::date = dd::date
group by gs.dd
order by gs.dd;

Обратите внимание, что это не использует неравенство в предложении on. Вместо этого он использует кумулятивные суммы в select. В целом, это предпочтительно с точки зрения производительности.

Возможно, вы захотите добавить where v.dte is not null, если updatedon может быть null.

...