postgresql - найти удержание из таблицы video_call - PullRequest
1 голос
/ 10 апреля 2020

Таблица:

create table video_call (
timestamp timestamp,
callerid int,
receiverid int,
call_length int);

insert into video_call values
('2018-12-12 01:01:01', 1, 2, 3),
('2019-01-01 01:01:01', 1, 3, 5),
('2019-01-01 01:01:01', 2, 4, 3),
('2019-01-01 01:01:01', 5, 6, 3),
('2019-01-02 01:01:01', 3, 4, 3),
('2019-01-02 01:01:01', 1, 4, 3),
('2019-01-03 01:01:01', 3, 5, 3),
('2019-01-03 01:01:01', 2, 5, 3),
('2019-01-04 01:01:01', 3, 7, 3);

найти новых пользователей на 2019-01-01 и затем получать коэффициент удержания этих новых пользователей за каждый день, начиная с 2019-01-0 до 2019-01-04.

Ожидаемый результат будет

day          |   retention
2019-01-02   |     0.5
2019-01-03   |     0.5
2019-01-04   |     0.25

Объяснение:

  • в день 2019-01-01, всего 4 новых пользователя 3, 4, 5, 6.
  • на 2019-01-02, есть 2 пользователя (3 и 4) из 4 новых пользователей, которые совершают видеозвонки.
  • на 2019-01-03, есть 2 пользователя (3 и 5) из 4 новых пользователей, совершающих видеозвонки.
  • на 2019-01-04, есть 1 пользователь (3) из 4 новые пользователи совершают видеозвонки.

Я пытался, но не мог найти способ сделать это. Ценю любую идею и вклад. Спасибо

Ответы [ 2 ]

0 голосов
/ 11 апреля 2020

на основе ввода @Gordon Linoff, я получаю решение, как показано ниже:

with cte1 as (
select date(timestamp) as day, callerid as user from video_call
union all
select date(timestamp) as day, receiverid as user from video_call),
cte2 as (
select c1.user from cte1 as c1 group by c1.user having min(day) = '2019-01-01'),
cte3 as (
select gs.day from generate_series('2019-01-01', '2019-01-04', interval '1 day') as gs(day)),
cte4 as (
select c3.day, c2.user from cte3 as c3 cross join cte2 as c2)
select c4.day, 
       round(count(distinct c1.user)/count(distinct c4.user)::decimal, 2) as retention 
from cte4 as c4 left join cte1 as c1
on c4.user = c1.user and c4.day = c1.day
group by c4.day;

здесь выводится:

enter image description here

0 голосов
/ 10 апреля 2020

Если вы хотите, чтобы клиенты начинали в один день, скажем, 2020-01-01, а затем смотрели, использовали ли они службу в течение нескольких дней, вам не нужен рекурсивный CTE. Я бы порекомендовал:

select gs.date,
       count(distinct vc.user) as num_users_on_day
from (select user, count(*) over (num_customers)
      from video_call
      group by user
      having min(timestamp)::date = '2020-01-01'::date
     ) u cross join
     generate_series('2020-01-01'::date, '2020-01-04'::date, interval '1 day') gs(dte) left join
     video_call vc
     on vc.user = u.user and vc.timestamp::date = gs.dte;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...