我有两个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,但实际上它仍然是空的。我正在寻找一种查询方式:
我特别关注“第二天晚于17:00:00计算”部分。这可能在(My)SQL中吗?
答案 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'