2013-07-16 6 views
2

У меня есть таблица с именем asset_usages, которая регистрирует просмотр объекта средством просмотра. Соответствующие поляХранить время между записями

id (int) 
asset_id (int) 
viewer_type (string) 
viewer_id (int) 
viewed_at (datetime) 

У меня есть новое поле я только что добавил под названием time_between_viewings, который представляет собой поле INT, представляющие секунды. Я хочу установить это время, в секундах, так как последний актив рассматривался. Таким образом, если я имел эти четыре записи:

+-----+----------+-----------+-------------+---------------------+-----------------------+ 
| id | asset_id | viewer_id | viewer_type | viewed_at   | time_between_viewings | 
+-----+----------+-----------+-------------+---------------------+-----------------------+ 
| 506 |  7342 |  1182 | User  | 2009-01-05 11:10:01 |  NULL    | 
| 509 |  7342 |  1182 | User  | 2009-01-05 11:12:47 |  NULL    | 
| 514 |  6185 |  1182 | User  | 2009-01-05 11:14:28 |  NULL    | 
| 524 |  6185 |  1182 | User  | 2009-01-05 11:28:18 |  NULL    | 
| 618 |  1234 |  1182 | User  | 2009-01-05 11:29:03 |  NULL    | 
| 729 |  1234 |  1182 | User  | 2009-01-05 11:29:01 |  NULL    |   
+-----+----------+-----------+-------------+---------------------+-----------------------+ 

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

+-----+----------+-----------+-------------+---------------------+-----------------------+ 
| id | asset_id | viewer_id | viewer_type | viewed_at   | time_between_viewings | 
+-----+----------+-----------+-------------+---------------------+-----------------------+ 
| 506 |  7342 |  1182 | User  | 2009-01-05 11:10:01 |  NULL    | 
| 509 |  7342 |  1182 | User  | 2009-01-05 11:12:47 |  166    | 
| 514 |  6185 |  1182 | User  | 2009-01-05 11:14:28 |  NULL    | 
| 524 |  6185 |  1182 | User  | 2009-01-05 11:28:18 |  830    | 
| 618 |  1234 |  1182 | User  | 2009-01-05 11:29:03 |  2    | 
| 729 |  1234 |  1182 | User  | 2009-01-05 11:29:01 |  NULL    |  
+-----+----------+-----------+-------------+---------------------+-----------------------+ 

, где 166 и 830 являются разница во времени между каждой парой, в секундах.

Каким будет sql для заполнения этого поля? Я не могу это понять.

ВАЖНОЕ ЗАМЕЧАНИЕ: данные не всегда вставляются в db в хронологическом порядке. Т.е. у вас могут быть две записи A и B, где B имеет более высокий идентификатор, но A имеет более позднее значение для view_at. Таким образом, поиск первой сопоставимой записи с более низким идентификатором не обязательно предоставит вам предыдущий просмотр одним и тем же человеком - вам нужно будет изучить все записи в базе данных.

спасибо! max

EDIT - указано, что time_between_viewings является полем int, представляющим секунды.

EDIT - добавил пару строк в качестве примера ряд с более высоким идентификатором, но ранее метки времени

EDIT - я просто понял, что я не оговаривают вопрос должным образом. Время_between_viewings должно быть равно времени, прошедшему с того момента, как актив последний раз просматривался тем же средством просмотра, то есть временем между записью и предыдущей (на основе view_at) записью, которая имеет те же объекты asset_id, viewer_id и viewer_type. Данные примера, которые я дал, все еще сохраняются, но я мог бы добавить несколько значений viewer_id и viewer_type, чтобы немного проиллюстрировать пример.

+0

Пожалуйста, при необходимости добавьте устройство в 'time_between_viewings', для будущих сопровождающих. По крайней мере, вы должны добавить комментарий к нему, если вы не можете изменить имя самого столбца. –

+0

* «данные не всегда вставляются в db в хронологическом порядке» * Добавьте несколько строк, которые иллюстрируют это ваши данные образца. –

+0

@ Clockwork-Muse - добавлено примечание о time_between_viewings –

ответ

0

Если было бы полезно, если бы вы подготовили таблицу образцов и вставки данных.
Прочитайте эту ссылку, чтобы узнать, почему это так важно, если вы хотите получить помощь: http://tkyte.blogspot.com/2005/06/how-to-ask-questions.html

На этот раз я создал его для вас, нажмите на эту ссылку: http://sqlfiddle.com/#!2/9719a/2

И попробуйте этот запрос (вы найдете это запрос вместе с образцами данных по вышеуказанной ссылке):

select alias1.*, 
     timestampdiff(second, previous_viewed_at, viewed_at) 
     as time_between_viewings 
from (
select alias.*, 
     (
     select viewed_at from (
      select 
      (select count(*) from asset_usages y 
       where x.asset_id = y.asset_id 
       and y.viewed_at < x.viewed_at 
      ) as rn, 
       x.* 
       from asset_usages x 
     ) xyz 
      where xyz.asset_id = alias.asset_id 
       and xyz.rn = alias.rn - 1 
     ) previous_viewed_at 
from (
    select 
    (select count(*) from asset_usages y 
     where x.asset_id = y.asset_id 
     and y.viewed_at < x.viewed_at 
    ) as rn, 
    x.* 
    from asset_usages x 
) alias 
) alias1; 
+0

Это заморозило мой сервер mysql (я убил его через 30 минут). Я забыл упомянуть, что у меня есть 800 000 + записей в таблице, я думаю, что это слишком много рекурсирует для обработки сервера. –

0

Этот оператор SELECT предоставит вам нужные данные. Возможно, вам придется сделать обновление в кусках.

Вы можете оставить предложение ORDER BY для инструкции UPDATE. Как написано, полученные данные не зависят от порядка строк во внешней инструкции SELECT.

select asset_id, viewer_id, viewer_type, viewed_at, 
     prev_viewed_at, timestampdiff(second, prev_viewed_at, viewed_at) elapsed_sec 
from (select asset_id, viewer_id, viewer_type, viewed_at, 
      (select max(t2.viewed_at) 
      from Table1 t2 
      where t2.viewed_at < Table1.viewed_at 
       and t2.asset_id = Table1.asset_id 
       and t2.viewer_id = Table1.viewer_id 
      ) prev_viewed_at 
     from Table1 
    )t3 
order by asset_id, viewer_id, viewed_at; 
Смежные вопросы