2012-04-06 45 views
0

我有两个MySQL表:统计(左)和消息(右)计数,每天的消息(17个以后计数第二天)

+------------+---------+  +---------+------------+-----------+----------+ 
    | _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零MSGCOUNT)
  • messages.time是24小时制。 AFTER 5点(17:00:00)所有的消息应该算第二天(通知MSG_ID 3和4计数2011-01-23)
  • 更新stats.msgcount持有所有罪状

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

回答

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) 

但是这个查询需要的约会,你有兴趣是在统计数据表中已经,如果你没有他们做出_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 
+0

感谢您的回复!顺便说一句 - 在_date和时间旁边还有一个带时间戳的列;那会更有效率吗? – Pr0no 2012-04-07 09:01:04

+0

只有在列中更正日期才能加快速度 - 然后您可以在该列上使用索引进行分组。如果您仍需要添加7小时或将日期部分作为时间戳,它不会有太大变化。 – piotrm 2012-04-07 12:52:27

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' 
+0

是的,表格是原样的。日志中不会添加(将来)。其次,如果它有帮助,消息表中还有一个时间戳列 - 可能这会使计算更容易? – Pr0no 2012-04-07 09:03:31