php - 单独获取从现在到 30 天前几天的 SQL 数据
问题描述
我正在构建一个分析图表,我需要在其中显示过去 30 天内每天的访问次数。我尝试使用下面的循环,但由于在一个请求中发送了 30 个查询,它无法提取某些数据并大大减慢了页面加载时间。
有没有更好的方法来从 MySQL 数据库中获取这些数据,同时节省服务器资源并改善页面的加载时间?任何帮助表示赞赏。
$conn = new mysqli("localhost", "db_host", "db_pwd", "db_name");
$d2 = date('c', strtotime('-29 days'));
$date = date("Y-m-d");
$begin = new DateTime($d2);
$end = new DateTime($date);
$end = $end->modify('+1 day');
$interval = new DateInterval('P1D');
$daterange = new DatePeriod($begin, $interval ,$end);
foreach($daterange as $date){
$current = $date->format("Y-m-d");
$sql = "SELECT COUNT(*) FROM stats WHERE link_id=$_GET[id] AND date='$current'";
$result = mysqli_query($conn, $sql);
if (mysqli_num_rows($result) > 0) {
while($row = mysqli_fetch_assoc($result)) { echo $row["COUNT(*)"]; }
} else { echo "no results";}
}
$conn->close();
解决方案
如果您每天至少访问一次,则可以使用聚合:
select date(dt) as dt_day, count(*) as cnt_visits
from stats
where link_id = ? and dt >= current_date - interval 29 day
group by date(dt)
order by dt_day
有一个名为的列date
在某种程度上具有误导性(尽管 MySQL 允许这样做)。为了清楚起见,我dt
在查询中将列重命名为。
如果有几天没有访问,并且您仍然想显示它们,并显示0
访问次数,那么它就有点棘手了。您需要先生成日期,然后left join
是表格。您通常会使用日历表 - 或者,在 MySQL 8.0 中,您可以使用递归公用表表达式即时执行此操作:
with recursive cte as (
select current_date as dt_day
union all
select dt_day - interval 1 day from cte where dt_day > current_date - interval 29 day
)
select c.dt_day, count(s.dt) as cnt_visits
from cte c
left join stats s
on s.link_id = ?
and s.dt >= c.dt_day
and s.dt < c.dt_day + interval 1 day
group by c.dt_day
order by c.dt_day
推荐阅读
- kubernetes - 通过 Kubernetes REST API 添加 pod 注解
- java - 我应该如何更改另一个类的值
- amazon-web-services - 如何在 Amazon Mechanical Turk 中使用同一组工人进行后续调查 HIT?
- java - 将两个容器添加到 main
- vba - 提示文件打开,进行更改并另存为另一个副本,然后关闭+取消保存原始文件
- java - 如何修改继承类的数组列表中的项目?
- javascript - 您好,我使用 checbox 处理 laravel 过滤器,但遇到了问题。我使用 ajax 和 jquery 来避免重新加载页面
- unity3d - 完成游戏后无法再次连接两个玩家自动谷歌玩游戏服务?
- sql - 将 SQL Server 动态游标转换为 Oracle
- php - 如果输入字段为空,则禁用提交按钮