每天计算消息(17:00后计算第二天)

时间:2012-04-06 23:14:22

标签: mysql sql date time

我有两个MySQL表:统计数据(左)和消息(右)

  +------------+---------+      +---------+------------+-----------+----------+
  |  _date     | msgcount|      | msg_id  | _date      | time      |  message |
  +------------+---------+      +----------------------+-----------+----------+
  | 2011-01-22 |  2      |      |   1     | 2011-01-22 |  06:23:11 | foo bar  |
  | 2011-01-23 |  4      |      |   2     | 2011-01-22 |  15:17:03 | baz      |
  | 2011-01-24 |  0      |      |   3     | 2011-01-22 |  17:05:45 | foobar   |
  | 2011-01-25 |  1      |      |   4     | 2011-01-22 |  23:58:13 | barbaz   |
  +------------+---------+      |   5     | 2011-01-23 |  00:06:32 | foo foo  |
                                |   6     | 2011-01-23 |  13:45:00 | bar foo  |
                                |   7     | 2011-01-25 |  02:22:34 | baz baz  |
                                +---------+------------+-----------+----------+

我填写了stats.msgcount,但实际上它仍然是空的。我正在寻找一种查询方式:

  • 计算每个stats._date的消息数(请注意2011-01-25上的零消息)
  • messages.time是24小时格式。 5点钟以后(17:00:00)的所有信息都应计入第二天(通知msg_id 3和4计算2011-01-23)
  • 更新stats.msgcount以保留所有计数

我特别关注“第二天晚于17:00:00计算”部分。这可能在(My)SQL中吗?

2 个答案:

答案 0 :(得分:3)

您可以使用:

UPDATE stats LEFT JOIN
  ( SELECT date(addtime(_date,time) + interval 7 hour) as corrected_date, 
           count(*) as message_count
    FROM messages
    GROUP BY corrected_date ) mc
ON stats._date = mc.corrected_date
SET stats.msgcount = COALESCE( mc.message_count, 0 )

但是,此查询要求您感兴趣的日期已经在stats表中,如果您没有它们,请将_date主键或唯一键(如果尚未使用)并使用:

INSERT IGNORE INTO stats(_date,msgcount)
SELECT date(addtime(_date,time) + interval 7 hour) as corrected_date,
       count(*) as message_count
FROM messages
GROUP BY corrected_date

答案 1 :(得分:1)

真的,你所做的只是把时间换了7个小时。这样的事情应该有效:

UPDATE stats s
SET count = (SELECT COUNT(msg_id) FROM messages m
             WHERE m._date BETWEEN DATE_SUB(DATE_ADD(s._date, INTERVAL TIME_TO_SEC(m.time) SECOND), INTERVAL 7 HOUR)
                               AND DATE_ADD(DATE_ADD(s._date, INTERVAL TIME_TO_SEC(m.time) SECOND), INTERVAL 17 HOUR));

基本思路是,它会在统计信息表格中记录每个日期,将其调整7小时,然后查找在该范围内发送的消息。如果您使用DATETIME列而不是单独的DATE和TIME列,则不需要额外的DATE_ADD(...,TIME_TO_SEC)内容。

可能有更好的方法来添加日期和时间,我没有看到一个快速查看MySQL参考文档。

所以你需要做的就是在stats表中插入一个新行,msgcount为0,然后运行update命令。如果您只想更新几天(因为消息计数可能在6天后没有变化),您只需要在更新中使用简单的where子句:

UPDATE stats s
SET ...
WHERE s._date BETWEEN '2012-04-03' AND '2012-04-08'