如何基于UNIX_TIMESTAMP查询今日全部记录?PHP统计攻击数异常求助
解决今日攻击事件统计的SQL问题
我来帮你搞定这个统计问题!你的原有SQL语句有两个关键问题导致结果不对,咱们一步步修正:
原语句的问题分析
- 类型不匹配:
CURDATE()返回的是日期格式(比如2024-05-20),而UNIX_TIMESTAMP()返回的是数字时间戳,用BETWEEN把这两种不同类型的值放一起,数据库无法正确解析范围。 - 区间逻辑错误:
DATE_SUB(CURDATE(), INTERVAL '-1' DAY)其实是取昨天的日期(负号在这里是多余的,写INTERVAL 1 DAY就会得到前一天),你的需求是统计今日,这个区间完全错了。
正确的查询方案(分两种字段类型)
情况1:date字段是DATETIME/DATE类型
如果你的logs表中date字段存储的是标准日期时间格式(比如2024-05-20 14:30:00),最简单的写法是直接匹配今日及以后的记录(因为CURDATE()会自动对应当天00:00:00):
$TodayAttacks = $odb->query("SELECT COUNT(id) FROM `logs` WHERE `date` >= CURDATE()")->fetchColumn(0);
如果要更严谨地限定到今日23:59:59,可以用日期区间:
$TodayAttacks = $odb->query("SELECT COUNT(id) FROM `logs` WHERE `date` BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 1 DAY)")->fetchColumn(0);
DATE_ADD(CURDATE(), INTERVAL 1 DAY)会得到明天的00:00:00,这样就完美覆盖了今日的所有时间范围。
情况2:date字段是UNIX时间戳(整数类型)
如果date字段存的是数字形式的时间戳(比如1716193800),需要把今日的时间范围转换成时间戳来匹配:
$TodayAttacks = $odb->query("SELECT COUNT(id) FROM `logs` WHERE `date` >= UNIX_TIMESTAMP(CURDATE())")->fetchColumn(0);
同样,严谨的区间写法是:
$TodayAttacks = $odb->query("SELECT COUNT(id) FROM `logs` WHERE `date` BETWEEN UNIX_TIMESTAMP(CURDATE()) AND UNIX_TIMESTAMP(DATE_ADD(CURDATE(), INTERVAL 1 DAY))")->fetchColumn(0);
这里UNIX_TIMESTAMP(CURDATE())会把今日00:00:00转换成对应的时间戳,确保只统计今日的攻击记录。
额外提示
如果你的date字段是DATETIME类型,还可以用DATE()函数提取日期部分来匹配:
$TodayAttacks = $odb->query("SELECT COUNT(id) FROM `logs` WHERE DATE(`date`) = CURDATE()")->fetchColumn(0);
不过这种写法会导致date字段上的索引失效,如果数据量很大的话,推荐用前面的范围查询(>= CURDATE()),性能更好。
内容的提问来源于stack exchange,提问作者Zac Ram
相关产品推荐
相关产品推荐

