2013-07-16 76 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填充此字段?我无法弄清楚。

重要提示:数据并不总是按时间顺序插入到数据库中。也就是说,你可以有两个记录A和B,其中B有一个更高的ID,但A有一个later_at的值。因此,查找具有较低ID的第一个匹配记录并不一定会让您以前由同一个人查看 - 您需要检查数据库中的所有记录。

谢谢!最大

编辑 - 指出time_between_viewings是一个代表秒的int字段。

编辑 - 添加了一排作为具有较高ID的行的例子,但早期的时间戳

编辑 - 我才意识到,我没有正确地规定的问题。 time_between_viewings应该等于资产上次查看的时间与相同的查看者,即记录与具有相同asset_id,viewer_id和viewer_type的前一个(基于viewing_at)记录之间的时间。我给出的示例数据仍然存在,但是我可以放入一些不同的viewer_id和viewer_type值来充实该示例。

+0

如果可以,请将此单元添加到'time_between_viewings'中,供将来的维护人员使用。如果您无法更改列本身的名称,则至少应该能够为其添加注释。 –

+0

*“数据并非总是按时间顺序插入数据库”*添加几行来说明您的样本数据。 –

+0

@ Clockwork-Muse - 添加了关于time_between_viewsings的笔记 –

回答

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语句将为您提供正确的数据。不过,您可能需要以块形式进行更新。

您可以删除UPDATE语句的ORDER BY子句。按照书面的说法,派生数据不依赖于外部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; 
相关问题