2013-09-25 2 views
1

У меня есть две таблицы: назовем их УСТАНОВКИ И ИСПОЛНИТЕ.LEFT OUTER JOIN with DATEDIF в Hive QL

Таблица INSTALLS имеет следующую структуру: user_id BIGINT, install_ts BIGINT.

Таблица EXECUTES имеет одинаковую структуру: user_id BIGINT, exec_ts BIGINT.

Пользователь user_id очевиден, поля _ts - это отметки времени, выраженные в секундах, отсчитываемых от эпохи Unix.

Эти две таблицы заполнит список, как это:

Каждый раз, когда пользователь устанавливает мое приложение, таблица INSTALLS заполняется. Затем он может удалить и переустановить, и в этом случае в этой таблице появится другая строка для одного и того же пользователя (разные ts, хотя). Для всего моего анализа мне нужно использовать самую старую временную метку установки.

Каждый раз, когда пользователь использует мое приложение, таблица EXECUTES заполняется - с user_id и временем выполнения.

Мне нужно создать сводную таблицу с этой структурой:

дата, кол-инсталляций на эту дату, счетчик использования на позднюю дату

Это, как я подошел к этой проблеме:

  1. Получить старую дату установки:

    ВЫБОР user_id, дАТУ (MIN (install_ts)) AS install_date FROM INSTALLS GROUP BY user_id

  2. Получить даты исполнения (необходимо для удовлетворения многочисленных казней в данной даты):

    ВЫБОР user_id, DATE (exec_ts) КАК exec_date ОТ Исполняет GROUP BY user_id, ДАТА (exec_ts)

  3. Смешайте эти два:

    ВЫБОР a.install_date, COUNT (a.user_id) А.С. install_count, COUNT (b.user_id) КАК usage_count ОТ (SELECT идентификатор_пользователя, дата (MIN (install_ts)) в install_date ОТ INSTALLS GROUP BY user_id) a LEFT OUTER JOIN(SELECT идентификатор_пользователя, DATE (exec_ts) AS exec_date ИЗ ГРУППЫ ПО Запускает user_id, дата (exec_ts)) б ПО 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 

И левые и правые псевдонимами встречаются в РЕГИСТРИРУЙТЕСЬ «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 

Но я вижу, что это просто неправильно - если пользователь устанавливает на 1 день и возвращается на 3-й день, он не будет учитываться в install_count (так как он не будет присутствовать в объединенной таблице). Так что теперь я вроде как из идей. Я немного новичок в SQL, поэтому любая помощь будет действительно оценена.

+0

проверить это решение с помощью ROW_NUMBER - http://www.dbforums.com/showthread.php?1669663-help-with-query-using-min-datediff – HuBeZa

ответ

2

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

Мое решение начинается с объединения двух таблиц (без группировки, которые вы использовали), а затем последующие операции используют функции аналитики, а затем группируются. В моем тестировании в таблицах использовались типы строк, поэтому даты выглядят как «2013-08-01» и т. Д., А также DATEDIFF.

Я создал промежуточную таблицу результатов соединения, но ее можно было легко свернуть в окончательный запрос. Эта таблица соединений будет содержать строку для каждого пользователя с датой установки и 1 или 0, чтобы указать, было ли выполнение на следующий день.

create table i_e_join as 
select i.user_id, i.install_ts, 
     if (e.exec_ts is null OR (DATEDIFF(e.exec_ts,i.install_ts) > 1), 0,1) 
     over (partition by i.user_id,i.install_ts) as has_exec 
from tmp_installs i left outer join tmp_executes e on (i.user_id = e.user_id); 

, а затем простая группа по, чтобы получить результат для каждого install_ts:

select install_ts, count(distinct user_id) as install_count, 
     sum(has_exec) as usage_count from i_e_join 
group by install_ts; 

Ключ для создания таблицы присоединиться используют аналитическую функцию для вычисления has_exec поля, которое смотрит через все строк от пользователя на install_ts.

1

Я решил это сам. Это, как я это сделал:

SELECT x.install_date, COUNT(x.user_id) AS install_count, COUNT(y.user_id) AS usage_count 
FROM (
    SELECT user_id, DATE(MIN(install_ts)) AS install_date FROM INSTALLS GROUP BY user_id 
) x LEFT OUTER JOIN (
    SELECT a.user_id AS user_id, a.install_date AS install_date, b.exec_date AS exec_date 
    FROM 
     (SELECT user_id, DATE(MIN(install_ts)) AS install_date FROM INSTALLS GROUP BY user_id) a 
     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 DATEDIFF(b.exec_date, a.install_date) = 1 
) y 
GROUP BY x.install_date