计算按年份分组的记录

时间:2015-08-29 01:21:16

标签: php mysql

我的表基本上是一个记录每个页面命中的访问日志。我想要显示的是每年每周的页面点击次数,每年比较一次(因此我有2013年,2014年,2015年第1周,2013年第2周,2014年等)。我目前正在通过查询所有记录来完成此任务,并让PHP执行如下繁重的工作:

$result=$db->query("select `time` from accessTracking where `uID` is not null and `time`>1357030861 order by `time`");
foreach($result as $r){
    $y=date("Y",$r['time']);
    $w=ltrim(date("W",$r['time']),'0');
    $accessArray[$w][$y]++;
}

虽然它可以工作,但是加载显示图形的页面需要7秒才能完成,我认为PHP不仅有更好的方法,而且MySQL更是如此(这就是我'我正在寻找,但我会采取任何可以减少页面加载时间的事情,并使整个事情变得更有效率。

所以,有了这个,我提出的最好的是:

select weekofyear(`time`) as week, count(*) as count from `accessTracking` where `uID` is not null group by week

这看起来像它会工作,因为它返回53行与"周" 1-52列和"计数"具有随机值的列,范围从2到1100.问题是数字应该更高,因为我拥有的最高周约为27,000次点击,并且此查询中返回的第一条记录为空"周&# 34;用"计数"价值约398,000。这告诉我,对于大多数记录,它没有计算weekofyear()值。

我的猜测是,我最终会将此作为每年的单独查询运行,因为将它返回年份,周数和计数可能太多了,所有这些都按照我想要的方式进行分组。但谁知道呢!

2 个答案:

答案 0 :(得分:2)

您的查询无法比较。特别是,第一个具有这种条件:

`time` > 1357030861

这表明time是一个unix时间。我建议你试试:

select weekofyear(from_unixtime(`time`)) as week, count(*) as count
from `accessTracking`
where `uID` is not null and `time` > 1357030861
group by week;

答案 1 :(得分:0)

首先,使用关键字或函数作为列名并不是一个好主意,因为它会导致混乱和bug的风险(并且必须记住所有的`字符)。我认为这会做你想要的,但随着年份添加到结果中。

select weekofyear(from_unixtime(`time`)) as wk,
       year(from_unixtime(`time`)) as yr,
       count(*) as ct
from `accessTracking`
where `uID` is not null
group by wk, yr

为了排查您看到的奇怪结果,您应该查询特定记录并查看它们与汇总的匹配情况。例如:

select `time` as access_time
from `accessTracking`
where `uID` is not null and
      weekofyear(from_unixtime(`time`)) = 1 and
      year(from_unixtime(`time`)) = 2015

将该查询的行数与聚合查询中的行数进行比较。他们应该匹配,如果他们不匹配,你可以更好地看出差异在哪里。当然,我建议选择行数较少的一周进行故障排除,或者选择显示您认为错误的结果的行。