2

所以我有一个看起来像这样的 MySQL 表:

id        timestamp                action        timePassed

1         2012-07-10 22:44:00      start         0
2         2012-07-10 22:44:50      pause         50
3         2012-07-10 22:45:30      play          50
4         2012-07-10 22:47:25      pause         205
5         2012-07-10 22:48:05      play          205

我不知道它有多明显,但这里发生的基本上是在每个“暂停”行上,我正在计算当前时间戳和“开始”行的时间戳之间的秒数差异。

我能想到的唯一方法是在数据库中插入一个新的“暂停”行,以便生成时间戳……然后在数据库中查询该“暂停”行的时间戳……计算以秒为单位的差异在“暂停”行和使用 PHP 的“开始”行之间......然后使用 timePassed 结果更新“暂停”行。

我的问题是是否有更好的方法来做到这一点(即使用 timediff 或其他一些 MySQL 命令)。问题是“暂停”时间戳在我进行 INSERT 之前不存在,所以我觉得需要先发生这种情况才能进行任何计算?

4

3 回答 3

0

我能想到的唯一方法是在数据库中插入一个新的“暂停”行,以便生成时间戳……然后在数据库中查询该“暂停”行的时间戳……计算以秒为单位的差异在“暂停”行和使用 PHP 的“开始”行之间......然后使用 timePassed 结果更新“暂停”行。

您可以插入已计算的行。

INSERT INTO table (timestamp, action, timePassed)
    SELECT now(), 'pause', SECOND(timediff(now(), timestamp))
    FROM table
    WHERE action = 'start'; -- and/or other WHERE clauses.

由于检索“开始”行所需的时间,这将引入时间偏差(但在操作上有索引(如果行非常大,可能还有时间戳),该时间应该可以忽略不计)。

于 2012-07-10T13:18:30.820 回答
0

好吧,如果您的桌子是这样的,而您的要求是这样的,那么您就走上了正轨。

但是,如果您检查最后一行和最后一行之间的第二个差异会更好。这将使您了解有多少第二个用户暂停或播放了曲目。

INSERT INTO table (timestamp, action, timePassed)
    SELECT now(), 'pause', SECOND(timediff(now(), timestamp))
    FROM table
    WHERE ID = (Select Max(ID) from Table)

随心所欲地采取行动,这样您就可以在两者之间插入时间差。

于 2012-07-10T13:22:16.020 回答
0

我建议根本不要timePassed显式存储,因为通过每个事件的时间戳,您已经将每个间隔存储了一次。如果您单独存储timePassed,您将在多个地方存储相同的数据。引用 EF Codd 的话,“如果某件事是真的,说两遍并不能让它变得更真实。” 此外,当您多次存储相同的内容时,您可能会遇到更新异常。

如果您想通过查询计算间隔,这可能会起作用。

SELECT event.id,
       event.timestamp,
       event.action,
       TIME_TO_SEC(TIMEDIFF(event.timestamp, start_event.timestamp)) time_passed
  FROM event
  JOIN (SELECT timestamp
          FROM event
         WHERE event.action = 'start') start_event ON 1 = 1
于 2012-07-10T13:37:03.897 回答