我有一个包含3列的表格:id
,updated_at
,click_sum
。
许多行具有完全相同的updated_at
值,这使得很难简单地检索数据order by updated_at
并在图表中显示总和。
由于相同日期有多个总和会使图表变得复杂。
我尝试实现的是获得以下输出:
update_at | click_sum
-----------+-----------
date1 | 100
date2 | 3
date3 | 235
date4 | 231
(可选)仅包含上个月,周或日AND
的日期,而不仅仅是NOW() - 1
个月的日期。
我构建的当前查询非常大,并且不能很好地工作。
它按日期分组(不显示重复日期)和SUM()
正确的点击次数,但定义日期(上个月,星期,日)时间似乎无法正常工作。
查询:($interval
代表MONTH
或DAY
或SECOND
或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
答案 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);