Как написать SQL-запрос для расчета случаев, когда строка, содержащая отличный идентификатор, происходит через 7 дней после первого появления уникального идентификатора? - PullRequest
0 голосов
/ 22 октября 2018

Я хочу вернуть дату, количество unique_id s первых вхождений в эту дату, число unique_id s, которое произошло через 7 дней после их первого появления, и процентное соотношение случаев после 7 дней / число первыхвхождения.

пример data_import таблица

+---------------------+------------------+
|         time        |   distinct_id    |  
+---------------------+------------------+
|      2018/10/01     |        1         |   first instance of `1`
+---------------------+------------------+
|      2018/10/01     |        2         |   also first instance, but does not occur 7 days later
+---------------------+------------------+
|      2018/10/02     |        1         |   should be disregarded (not first instance of 1)
+---------------------+------------------+
|      2018/10/02     |        3         |   first instance of `3`
+---------------------+------------------+
|      2018/10/08     |        1         |   First instance 7 days after first instance of `1`
+---------------------+------------------+
|      2018/10/08     |        1         |   Don't count as this is the 2nd instance of `1` on this day 
+---------------------+------------------+
|      2018/10/09     |        3         |   7 days after first instance of `3`
+---------------------+------------------+
|      2018/10/09     |        1         |   7 days after non-first instance of `1`
+---------------------+------------------+

И ожидаемый результат.

+---------------------+----------------------+------------------------+---------------------------+
|       time          | num_of_1st_instance  | num_occur_7_days_after | percent_used_7_days_after |  
+---------------------+----------------------+------------------------+---------------------------+
|     2018/10/01      |         2            |          1             |           .50             |  
+---------------------+----------------------+------------------------+---------------------------+
|     2018/10/02      |         1            |          1             |            1.0            |  
+---------------------+----------------------+------------------------+---------------------------+
|     2018/10/03      |         0            |          0             |             0             |  
+---------------------+----------------------+------------------------+---------------------------+

Написанный мною запрос близок, но подсчитывает вхождения, отличные от первого дляa distinct_id.

В моем примере этот запрос будет включать в себя вхождение distinct_id 1 в 2018/10/02 и его выполнение через семь дней после 2018/10/02 в 2018/10/09.Не требуется, поскольку 2018/10/02 вхождение distinct_id 1 не является первым.

SELECT
  data_import.time AS date,
  count(distinct data_import.distinct_id) AS num_installs_on_install_date,
  count(distinct future_activity.distinct_id) AS num_occur_7_days_after,
  count(distinct future_activity.distinct_id) / count(distinct data_import.distinct_id)::float AS percent_used_7_days_after
FROM data_import
LEFT JOIN data_import AS future_activity ON
  data_import.distinct_id = future_activity.distinct_id
    AND
  DATE(data_import.time) = DATE(future_activity.time) - INTERVAL '7 days'
    AND
  data_import.time = ( SELECT
                             time
                           FROM
                             data_import
                           WHERE
                             distinct_id = future_activity.distinct_id
                           ORDER BY
                             time
                           limit
                             1 )
GROUP BY DATE(data_import.time)

Я надеюсь, что я объяснил это ясно.Пожалуйста, дайте мне знать, как я могу изменить свой текущий запрос или другой подход к решению.

1 Ответ

0 голосов
/ 22 октября 2018

Хммм.Делает ли это то, что вы хотите?

select di.time, sum( (seqnum = 1)::int) as first_instance,
       sum( flag_7day ) as num_after_7_day,
       sum( (seqnum = 1)::int) * 1.0 / sum( flag_7day ) as ratio
from (select di.*, 
             row_number() over (partition by distinct_id order by time) as seqnum,
             (case when exists (select 1 from data_import di2 where di2.distinct_id = di.distinct_id and di2.time > di.time + interval '7 day')
                   then 1 else 0
              end) as flag_7day
      from data_import di
     ) di
group by di.time;

Это не возвращает дни без первых экземпляров.Те дни кажутся немного неловкими в отношении соотношения, поэтому я не уверен на 100%, что они вам действительно нужны.Если вы это сделаете, достаточно просто включить generate_series(), чтобы сгенерировать все даты в нужном диапазоне.

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