У меня есть две таблицы: назовем их INSTALLS и EXECUTES.
Таблица INSTALLS имеет структуру: user_id BIGINT, install_ts BIGINT.
Таблица EXECUTES имеет ту же структуру: user_id BIGINT, exec_ts BIGINT.
User_id очевиден, поля _ts - это временные метки, выраженные в секундах, отсчитываемых от эпохи Unix.
Эти две таблицы заполняются следующим образом:
Каждый раз, когда пользователь устанавливает мое приложение, таблица INSTALLS заполняется. Затем он может удалить и переустановить, и в этом случае в этой таблице появится другая строка для того же пользователя (правда, разные ts). Для всего моего анализа мне нужно использовать самую старую метку времени установки.
Каждый раз, когда пользователь использует мое приложение, таблица EXECUTES заполняется - с user_id и временем выполнения.
Мне нужно создать сводную таблицу с такой структурой:
дата, количество установок на эту дату, количество использований на последующую дату
Вот как я подошел к проблеме:
Получить самую старую дату установки:
ВЫБЕРИТЕ user_id, DATE (MIN (install_ts)) AS install_date FROM INSTALLS GROUP BY user_id
Получить даты выполнения (необходимо учитывать несколько выполнений в заданную дату):
ВЫБРАТЬ user_id, DATE (exec_ts) AS exec_date FROM EXECUTES GROUP BY user_id, DATE (exec_ts)
Объедините эти два:
ВЫБЕРИТЕ a.install_date, COUNT (a.user_id) AS install_count, COUNT (b.user_id) AS usage_count FROM (SELECT user_id, DATE (MIN (install_ts)) AS install_date FROM INSTALLS GROUP BY user_id) a LEFT OUTER JOIN (SELECT user_id, DATE (exec_ts) AS exec_date FROM EXECUTES GROUP BY user_id, DATE (exec_ts)) b ON a.user_id = b.user_id GROUP BY a.install_date
Это будет учитывать всех пользователей, которые использовали мое приложение в любое время. Из этого набора данных мне теперь нужно извлечь только тех пользователей, которые использовали мое приложение сразу после даты их установки.
Один из подходов, который я рассмотрел, заключался в наличии дополнительного условия JOIN. Когда я это сделаю, я получаю (сначала запрос, ниже ошибка):
SELECT a.install_date, COUNT(a.user_id) AS install_count, COUNT(b.user_id) AS usage_count
FROM
(SELECT user_id, DATE(MIN(install_ts)) AS install_date FROM INSTALLS GROUP BY user_id) a
LEFT OUTER JOIN
(SELECT user_id, DATE(exec_ts) AS exec_date FROM EXECUTES GROUP BY user_id, DATE(exec_ts)) b
ON a.user_id = b.user_id AND DATEDIFF(b.exec_date, a.install_date) = 1
GROUP BY a.install_date
И левый, и правый псевдонимы встречаются в JOIN '1'
Второй подход, который я рассмотрел, заключался в том, чтобы иметь DATEDIFF в предложении WHERE:
SELECT a.install_date, COUNT(a.user_id) AS install_count, COUNT(b.user_id) AS usage_count
FROM
(SELECT user_id, DATE(MIN(install_ts)) AS install_date FROM INSTALLS GROUP BY user_id) a
LEFT OUTER JOIN
(SELECT user_id, DATE(exec_ts) AS exec_date FROM EXECUTES GROUP BY user_id, DATE(exec_ts)) b
ON a.user_id = b.user_id
WHERE b.user_id IS NULL OR DATEDIFF(b.exec_date, a.install_date) = 1
GROUP BY a.install_date
Но я вижу, что это просто неправильно - если пользователь устанавливает в первый день и возвращается в третий день, он не будет засчитан в install_count (поскольку он не будет присутствовать в объединенной таблице). Так что теперь у меня закончились идеи. Я немного новичок в SQL, поэтому я буду благодарен за любую помощь.