2016-02-23 5 views
3

У меня есть набор данных с 4 (соответствующие столбцы): уникальный id, user_id, time_stamp, event. Уникальный идентификатор является первичным ключом, user_id может быть повторен, time_stamp (datetime) принимается при возникновении события, событие - либо a) push-уведомление (push), либо b) приложение открытия пользователя (открыто).Расчет разницы между временами

Это может выглядеть следующим образом:

id user_id time_stamp event count it? 
1  1   10   open 
2  1   23   push -good 
3  1   28   open 
4  1   38   push -bad 
5  1   65   open 
6  1   85   push -good 
7  1   89   open 
8  1   28   push -bad 
9  2   38   push -good 
10  2   45   open 
11  2   46   open 

Я пытаюсь выяснить, если мои уведомления толчка полезны. Для этого мне нужно узнать, откроет ли пользователь приложение в течение 20 минут после push-уведомления. Я посчитаю это «успешным толчком», тогда как все остальные толчки не будут успешными. До сих пор у меня была идея, чтобы внутреннее соединение таблицы было само собой, но у меня проблема с дублированными строками. Например, мы получим ложные срабатывания с идентификаторами 4, потому что нужно учитывать только id 3.

SELECT * FROM 
    (SELECT * FROM table WHERE row = 'open') a 
    INNER JOIN (SELECT * FROM table WHERE row = 'push') b 
    ON a.user_id = b.user_id) WHERE a.time_stamp - b.timestamp < 20; 
+0

так как 3 - открытое действие и показывает, что нажатие уже полезно, вы не хотите считать 4? –

+0

С моим исходным запросом идентификатор 4 подсчитывался по нажатию на id 2. Мы просто хотим посмотреть, приходят ли пользователи в приложение. –

ответ

0

Вы можете попробовать что-то вроде этого:

SELECT t1.id, t1.user_id, t1.time_stamp, t1.event, 
     t2.id, t2.time_stamp, t2.event  
FROM mytable AS t1 
INNER JOIN mytable AS t2 
    ON t1.user_id = t2.user_id AND t1.event = 'push' AND t2.event = 'open' AND 
     t2.time_stamp > t1.time_stamp AND t2.time_stamp - t1.time_stamp < 20 
LEFT JOIN mytable AS t3 
    ON t3.user_id = t2.user_id AND t3.event = 'open' AND 
     t3.time_stamp > t1.time_stamp AND t3.time_stamp < t2.time_stamp 
WHERE t3.id IS NULL 

Выход:

id, user_id, time_stamp, event, id, time_stamp, event 
===================================================== 
2, 1,  23,   push, 3, 28,  open 
8, 2,  28,   push, 10, 45,  open 
9, 2,  38,   push, 10, 45,  open 

Примечание: Вам нужен дополнительный LEFT JOIN, если вам нужно отфильтровать записи с id = 8 ,

+0

Это * кажется слишком сложным - но у меня еще не было утреннего кофе, так что, возможно, я пропустил что-то – Strawberry

1

Поскольку у вас есть несколько записей для одного и того же user_id, я предполагаю, что вы хотите взять последний «open» time_stamp и сравнить это с последним «push» для каждого пользователя?

Если это так, я думаю, что следующий делает то, что вы хотите (нужен прибраться, но должны сделать трюк):

SELECT et4.User_id, ts1, et3.User_id, ts2 
FROM 
(SELECT et1.user_id, max(et1.time_stamp) as ts1 from eventtable as et1 
where et1.event = 'push' 
group by et1.user_id 
) as et4 
INNER JOIN 
(SELECT et2.user_id, max(et2.time_stamp) as ts2 from eventtable as et2 
where event = 'open' group by et2.user_id) as et3 
ON et3.user_id = et4.user_id 
WHERE ts2 -ts1 < 20 

В основном, выберите последний толчок для каждого пользователя и присоединиться к этому последним открытым для этот пользователь, затем вычислить разницу в метке времени.

Надеюсь, это поможет.

+0

Это очень полезно. Еще одна вещь: что, если у меня есть user_id, который имеет два события push/open под тем же user_id? В вашем запросе мы получим только один набор user_id. –

+0

Рад помочь. Запрос будет получать последние «push» и последние «открытые» для каждого пользователя. Поэтому он не будет анализировать несколько событий push/open для одного и того же пользователя (кажется, что вам это может понадобиться). Это также может быть не идеальным, если есть один «push», за которым следует несколько открываний, поскольку он смотрит только на последний «открытый». Из того, что вы говорите, может быть лучше выбрать каждый «открытый», а затем найти соответствующий следующий «push» (примечание ** далее ** не последнее). Возможно, раскройте исходный вопрос немного подробнее о том, что вам нужно сейчас, у вас есть этот запрос в качестве основы. – Alan

Смежные вопросы