为什么今天会从退回的值中排除?
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
不正确。
答案 0 :(得分:1)
除非您将数据写入此表的方式有些奇怪,否则您的查询没有理由排除当天的数据。您可能没有看到它,因为您没有订购结果(即它位于结果集的底部)?
这将是30天前的一天的部分日结果。因此,您可以考虑稍微修改WHERE条件:
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);
答案 1 :(得分:0)
你的句子很完美,事实上SELECT (NOW() - INTERVAL 30 DAY)
会返回2013-12-18 22:33:30
。我尝试了类似的奇怪问题,这是因为我们的DDBB服务器具有与Apache服务器不同的时间配置,并且它给我们带来了奇怪的结果。
检查服务器时间配置,(http://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html)
答案 2 :(得分:-1)
您可以在the PHP manual中的评论中看到人们遇到麻烦,包括迭代DatePeriod
时的结束日期。那里提出了各种修改可以帮助解决这个问题,但是对于你正在做的事情,你并不需要结束日期,因为你总是只是从当前日期返回一定天数。
您可以使用the DatePeriod
constructor的“重复”表单来包含结束日期。
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);