获取上个月,周,日的重复日期条目的总和

时间:2012-04-05 15:10:12

标签: php mysql sql

我有一个包含3列的表格:idupdated_atclick_sum

许多行具有完全相同的updated_at值,这使得很难简单地检索数据order by updated_at并在图表中显示总和。 由于相同日期有多个总和会使图表变得复杂。

我尝试实现的是获得以下输出:

 update_at | click_sum
-----------+-----------
   date1   |    100
   date2   |     3
   date3   |    235
   date4   |    231

(可选)仅包含上个月,周或日AND的日期,而不仅仅是NOW() - 1个月的日期。

我构建的当前查询非常大,并且不能很好地工作。 它按日期分组(不显示重复日期)和SUM()正确的点击次数,但定义日期(上个月,星期,日)时间似乎无法正常工作。

查询:($interval代表MONTHDAYSECONDWEEK

SELECT d.updated_at, SUM(d.clicks_sum) AS click_sum
FROM aggregated_clicks d
JOIN 
(
     SELECT c.id, MAX(StartOfChains.updated_at) AS ChainStartTime
     FROM aggregated_clicks c
     JOIN 
     (
         SELECT DISTINCT a.updated_at
         FROM aggregated_clicks a
         LEFT JOIN aggregated_clicks b ON (b.updated_at >= a.updated_at - INTERVAL 1 DAY AND b.updated_at < a.updated_at)
         WHERE b.updated_at IS NULL
      ) StartOfChains  ON c.updated_at >= StartOfChains.updated_at
     GROUP BY c.id
) GroupingQuery
ON d.id = GroupingQuery.id
WHERE GroupingQuery.ChainStartTime >= DATE_SUB(NOW(), INTERVAL 1 $interval)
GROUP BY GroupingQuery.ChainStartTime
ORDER BY GroupingQuery.ChainStartTime ASC

1 个答案:

答案 0 :(得分:1)

也许我对你的问题(以及它引用的表格)的性质做了太多假设,但我认为这可以比你所展示的查询更简单。

确定最近完成的月份并不是很难。

首先要知道当前月份的第一个日期 - 使用此:

date_sub(curdate(), interval (extract(day from curdate())-1) day)

要知道上个月的第一天,请使用:

date_sub(date_sub(curdate(), interval extract(day from (curdate())-1) day), interval 1 month)

所以,如果你想获得两者之间的天数 - 即最近完成的月份,请使用:

select updated_at, sum(click_sum) from aggregated_clicks
  where updated_at >= date_sub(date_sub(curdate(), interval extract(day from (curdate())-1) day), interval 1 month)
    and updated_at < date_sub(curdate(), interval (extract(day from curdate())-1) day)
  group by updated_at;

确定最新完成的一周同样容易。这个例子将假设一个星期日到星期六的星期。

由于ODBC标准定义日期编号的方式,很容易找到上周的结束(星期六):

date_sub(curdate(), interval dayofweek(curdate()) day)

并且该周的开始(星期日)是在此之前的六天:

date_sub(curdate(), interval (dayofweek(curdate())+6) day)

所以,如果你想获得两者之间的天数 - 即最近完成的一周,请使用:

select updated_at, sum(click_sum) from aggregated_clicks
  where updated_at >= date_sub(curdate(), interval (dayofweek(curdate())+6) day)
    and updated_at <= date_sub(curdate(), interval dayofweek(curdate()) day)
  group by updated_at;

当然,根据最新完成的日期进行计算非常容易。

获取前一天的日期,请使用:

date_sub(curdate(), interval 1 day)

所以如果你想要昨天的总和,请使用:

select updated_at, sum(click_sum) from aggregated_clicks
  where updated_at = date_sub(curdate(), interval 1 day)
  group by updated_at;

注意:我已经使用MySQL 5.1,YMMV测试了这些查询。

----------

更新:由于日期列是日期时间,只需将我的查询中对updated_at的所有引用更改为date(updated_at),如下所示:

月案例:

select date(updated_at), sum(click_sum) from aggregated_clicks
  where date(updated_at) >= date_sub(date_sub(curdate(), interval extract(day from (curdate())-1) day), interval 1 month)
    and date(updated_at) < date_sub(curdate(), interval (extract(day from curdate())-1) day)
  group by date(updated_at);

周案例:

select date(updated_at), sum(click_sum) from aggregated_clicks
  where date(updated_at) >= date_sub(curdate(), interval (dayofweek(curdate())+6) day)
    and date(updated_at) <= date_sub(curdate(), interval dayofweek(curdate()) day)
  group by date(updated_at);

昨天的案例:

select date(updated_at), sum(click_sum) from aggregated_clicks
  where date(updated_at) = date_sub(curdate(), interval 1 day)
  group by date(updated_at);