0

I have a table with 3 columns: id, updated_at, click_sum.

Many rows have the exact same updated_at value which makes it hard to simply retrieve the data, order by updated_at and display the sums in a chart. Since there are multiple sums for the same dates which screws the chart.

What I try to achieve is to get the following output:

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

Optionally only those dates which are form the last month, week or day AND not simply the dates which are NOW() - 1 month.

The current query I build is very large and doesn't work that well. It groups by dates (no duplicated dates appear) and SUM()s the clicks correctly but defining from when (last month, week, day) the dates are doesn't seem to work properly.

Query: ($interval stands for MONTH or DAY or SECOND or WEEK)

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
4

1 回答 1

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);
于 2012-04-07T11:47:10.990 回答