mySQL在每条消息的时间范围内显示日志?

时间:2014-04-12 20:19:06

标签: mysql sql

是否可以在一个查询中执行此操作?例如,我有一个名为logs的表,其中包含以下列:id,epoch,username,msg。

我需要搜索来自某个用户的消息,如下所示:

select * from logs where username = 'bob'

现在我想在该消息的特定时间范围内选择来自bob的所有消息。

我知道我可以使用for循环在PHP中轻松完成此操作,但我必须使用mySQL。

我原本想做这样的事情:

select * from logs where FROM_UNIXTIME(epoch) between
(select FROM_UNIXTIME(epoch) from logs where username = 'bob')
and
ADDTIME((select FROM_UNIXTIME(epoch) from logs where username = 'bob'), '03:00:00')

但这不起作用,因为我的子查询将返回多个值。

我该怎么做?

编辑:我想用多条消息来做这件事,例如,一些伪代码:

foreach epoch, message in (messages from logs where username = bob) as a do
print (select epoch, username, message from logs where epoch between a.epoch and ADDTIME(a.epoch, 3 hours))
end

但我必须使用mySQL。是否可以在mySQL中执行此操作?

1 个答案:

答案 0 :(得分:1)

而不是任何类型的子查询,听起来像你想要的表格可以通过表的LEFT JOIN来实现,但不是简单的连接条件,而是使用epoch BETWEEN ...加入ON子句中的条件。

联接的左侧将被过滤到username = 'bob',而右侧将在相关数据范围内找到消息。

如果需要,添加DISTINCT重复数据删除行。

SELECT
  DISTINCT
  rng.epoch,
  rng.username,
  rng.message
FROM
  logs AS main
  LEFT JOIN logs as rng 
    /* Join the epoch values from the table to related rows within 3 hours */
    ON rng.epoch BETWEEN main.epoch AND (a.epoch + INTERVAL 3 HOUR)
/* filter the main one for the desired username */
WHERE main.username = 'bob'

从您的问题中可以清楚地知道您最终是否只想要返回bob行。如果是这种情况,则需要在WHERE子句中过滤联接的两端,或者在ON子句中匹配的用户名:

FROM
  logs AS main
  LEFT JOIN logs as rng 
    ON rng.epoch BETWEEN main.epoch AND (a.epoch + INTERVAL 3 HOUR)
    /* match usernames so the related rows are only bob's
    AND main.username = rng.username