Интервалы между двумя датами с группировкой

118
05 ноября 2021, 18:50

Есть таблица, в которой:

  event_name(Purchase, SessionStartm, SessionEnd)
, event_time
, user_id
, registration_time

В рамках одного пользователя последовательность событий во времени может выглядеть примерно так:

  1. SessionStart
  2. SessionEnd
  3. SessionStart
  4. Purchase
  5. SessionEnd
  6. SessionStart
  7. SessionEnd
  8. SessionStart
  9. Purchase
  10. SessionEnd

Задача: для пользователей, зарегистрировавшихся в игре за последние 100 дней, получить распределение по времени, проведённому в игре, до совершения первой покупки.

Ответ должен выглядеть примерно так:

┌─time─┬─users_count─┐
│ 1200 │          10 │
│ 1260 │          13 │
│ 1320 │          17 │
│ 1380 │          19 │
│ 1440 │           1 │
│ 1500 │           8 │
│ 1560 │          11 │
└──────┴─────────────┘
Answer 1

PostgreSQL. Для MySQL придётся использовать его функции работы с интервалами. Не уверен, можно ли проще, но как-то так:

WITH earliest_events AS (
  SELECT MIN(event_id) AS event_id
       , MIN(event_time) AS event_time
    FROM events
   GROUP BY event_name
       , user_id
)
, user_times AS (
  SELECT user_id
       , TRUNC(
           EXTRACT(EPOCH FROM purchase.event_time - start.event_time) / 60
         ) * 60 AS time
    FROM events AS start
         INNER JOIN earliest_events AS earliest_starts
            ON start.event_id = earliest_starts.event_id
          LEFT JOIN events AS purchase
         USING (user_id) 
         INNER JOIN earliest_events AS earliest_purchases
            ON purchase.event_id = earliest_purchases.event_id
   WHERE start.event_name = 'SessionStart'
     AND purchase.event_name = 'Purchase'
)
SELECT time
     , COUNT(user_id) AS users_count
  FROM user_times
 GROUP BY time
;
 time | users_count 
------+-------------
   60 |           2
  120 |           1

DB-Fiddle: https:// www.db-fiddle.com/f/bmoFYZm8hjDnNNrJkkttUF/0.

Вторая версия, без event_id. Так как вы так и не указали, что в таблице является первичным ключом, я взял сочетание user_id и event_time. Если и это не является первичным ключом — сами.

WITH earliest_events AS (
  SELECT MIN(event_time) AS event_time
       , user_id
    FROM events
   GROUP BY event_name
       , user_id
)
, user_times AS (
  SELECT start.user_id
       , TRUNC(
           EXTRACT(EPOCH FROM purchase.event_time - start.event_time) / 60
         ) * 60 AS time
    FROM events AS start
         INNER JOIN earliest_events AS earliest_starts
            ON start.event_time = earliest_starts.event_time
           AND start.user_id = earliest_starts.user_id
          LEFT JOIN events AS purchase
            ON start.user_id = purchase.user_id
         INNER JOIN earliest_events AS earliest_purchases
            ON purchase.event_time = earliest_purchases.event_time
           AND purchase.user_id = earliest_purchases.user_id
   WHERE start.event_name = 'SessionStart'
     AND purchase.event_name = 'Purchase'
)
SELECT time
     , COUNT(user_id) AS users_count
  FROM user_times
 GROUP BY time
;
READ ALSO
логика при работе с псевдоклассом :hover

логика при работе с псевдоклассом :hover

Первое правило прячет список-подменюВторое - показывает подменю, если на верхний пункт меню (родитель), в котором находится подменю, наведут...

119
Не прогружаются стили css

Не прогружаются стили css

У меня есть заказчик с Турции и у него сайт выглядит так как будто там не прогрузился CSS, а у меня всё норм долго не мог понять в чём проблема...

199
Установка фона для контейнера

Установка фона для контейнера

Прошу помощи в следующей задаче: Хочу реализовать адаптивную секцию с текстом и изображением 50/50 на полный экранЖелательно в CSS самым элементарным...

128