为什么今天从返回的值中排除?
SELECT DATE(created) AS reg_date,
COUNT(*) AS user_reg_per_day
FROM users
WHERE created > (NOW() - INTERVAL 30 DAY)
GROUP BY reg_date
我的查询似乎很好,但是我使用以下PHP来填补空白:
function generate_calendar_days() {
$end = date("Y-m-d");
$today = strtotime($end);
$start = strtotime("-30 day", $today);
$start = date('Y-m-d', $start);
$range = new DatePeriod(
DateTime::createFromFormat('Y-m-d', $start),
new DateInterval('P1D'),
DateTime::createFromFormat('Y-m-d', $end));
$filler = array();
foreach($range as $date) {
$d = $date->format('Y-m-d');
$filler[$d] = 0;
}
return $filler;
}
我的猜测是$today
不正确。
没有理由您的查询应排除当天的数据,除非您将数据写入此表有一些奇怪的方式。您可能没有看到它是因为您没有订购结果(即它在结果集的底部)?
它将给出30天前一天的部分结果。因此,您可以考虑修改某些情况:
SELECT DATE(created) AS reg_date,
COUNT(*) AS user_reg_per_day
FROM users
WHERE created >= DATE(DATE_SUB(NOW(),INTERVAL 30 DAY))
GROUP BY reg_date
ORDER BY reg_date DESC
以下是对更新问题的评论,因为似乎问题在PHP代码中。
我不完全理解为什么您会将Strtotime功能与DateTime,DateInterval,DatePeriod混合在一起。很高兴看到您正在使用这些,因为许多开发人员都大为充分利用。
说我可能会将该功能重写为:
function generate_calendar_days($start = 'today', $days = 30, $days_in_past = true) {
$dates = array();
try {
$current_day = new DateTime($start); // time set to 00:00:00
} catch (Exception $e) {
echo ('Failed with: ' . $e->getMessage());
return false;
}
$interval = new DateInterval('P1D');
if (true === $days_in_past) {
$interval->invert = 1; // make days step back in time
}
$range = new DatePeriod($current_day, $interval, $days);
foreach($range as $date) {
$dates[] = $date->format('Y-m-d');
}
return $dates;
}
请注意,在这里,我添加了参数以使您的功能更灵活。我也只返回一系列日期字符串,以使功能更具通用。您可以将如何与此功能范围之外的实现细节一起使用如何使用。
您可以轻松地在函数调用之外构建零填充的数组:
$calendar = array_fill_keys(generate_calendar_days(), 0);
您的句子很完美,实际上SELECT (NOW() - INTERVAL 30 DAY)
返回2013-12-18 22:33:30
。我试验了类似的奇数问题,这是因为我们的DDBB服务器的时间配置与Apache Server不同,并且避免了我们的奇怪结果。
检查服务器时间配置,(http://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html)
您可以从PHP手册中的注释中看到人们遇到的麻烦,包括迭代DatePeriod
的结束日期。建议那里有各种各样的修改可以帮助您解决这个问题,但是对于您的工作,您并不需要结束日期,因为您总是从当前日期开始固定的天数。
您可以使用DatePeriod
构造函数的"复发"形式包括结束日期。
function generate_calendar_days(int $n): array
{
$range = new DatePeriod(new DateTime("-$n day"), new DateInterval('P1D'), $n);
foreach($range as $date) {
$filler[$date->format('Y-m-d')] = 0;
}
return $filler;
}
$days = generate_calendar_days(30);