我有一个名为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具有更高的lit_at值。因此,查找具有较低ID的第一个匹配记录不一定会让您先前查看同一个人 - 您需要检查数据库中的所有记录。
谢谢!最大
编辑 - 声明time_between_viewings是一个表示秒的int字段。
编辑 - 添加了几行作为具有更高内容但更早时间戳的行的示例
编辑 - 我刚刚意识到我没有正确地规定这个问题。 time_between_viewings应该等于同一个查看者上次查看资产以来的时间,即记录与具有相同asset_id,viewer_id和viewer_type的上一个(基于Viewed_at)记录之间的时间。我给出的示例数据仍然保留,但我可以放入一些不同的viewer_id和viewer_type值来稍微充实示例。
答案 0 :(得分: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;
答案 1 :(得分: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;