按日期分组的 MySQL 累积总和
Posted
技术标签:
【中文标题】按日期分组的 MySQL 累积总和【英文标题】:MySQL cumulative sum grouped by date 【发布时间】:2014-04-12 04:13:57 【问题描述】:我知道有一些与此相关的帖子,但我的情况有点不同,我想在这方面获得一些帮助。
我需要从数据库中提取一些数据,这些数据是每天累积的交互次数。目前这就是我所拥有的
SELECT
e.Date AS e_date,
count(e.ID) AS num_interactions
FROM example AS e
JOIN example e1 ON e1.Date <= e.Date
GROUP BY e.Date;
这个输出接近我想要的,但不完全是我需要的。
我遇到的问题是日期与交互发生的小时分钟和秒一起存储,因此 group by 不会将日期分组在一起。
这是输出的样子。
在 12-23 有 5 次互动,但没有分组,因为时间戳不同。所以我需要想办法忽略时间戳,只看一天。
如果我尝试GROUP BY DAY(e.Date)
,它只会按天对数据进行分组(即任何一个月的 1 日发生的所有事情都被分组到一行中),而输出根本不是我想要的。
GROUP BY DAY(e.Date), MONTH(e.Date)
正在按月份和日期进行拆分,但计数再次关闭。
我根本不是 mysql 专家,所以我对自己缺少什么感到困惑
【问题讨论】:
【参考方案1】:昨晚我想出了我需要做的事情......但由于我是新手,所以我无法发布它......我所做的工作是这样的:
SELECT
DATE(e.Date) AS e_date,
count(e.ID) AS num_daily_interactions,
(
SELECT
COUNT(id)
FROM example
WHERE DATE(Date) <= e_date
) as total_interactions_per_day
FROM example AS e
GROUP BY e_date;
这会比您的查询效率低吗?如果效率更高,我可能会在提取每天的计数后在 python 中进行计算,因为这将返回数千到数十万行。
【讨论】:
您的查询看起来不错。只需确保您的日期比较符合您的预期,因为您将日期类型与日期时间类型进行比较。 响应是我想要的。我只是有点犹豫,因为随着这张桌子的增长它会很慢。再次感谢您所做的一切.. 非常有帮助 我会尝试解释这两个查询。我觉得这个会为每个日期运行子查询,如果我们有适当的索引,这应该不会很慢,但是@clheristian's 做了一个分组,然后迭代它,这可能会更好(特别是如果 -这是我的情况——你有额外的、非索引的过滤条件)。 @chesterbr 我最终更改了此查询,因为它需要一段时间。如果您查看我最近的问题,我会问一个关于优化它的问题.. 结束了两个查询,只是在 python 中进行累积计数...当将 300,000 条记录与自身进行比较时,查询开始需要 14-15 秒才能运行.. 有 90,000,000,000 行要检查.. 它的索引和优化仍然需要一些时间来比较。【参考方案2】:新答案
起初,我不明白您是在尝试计算总和。下面是它的外观:
SET @runningTotal = 0;
SELECT
e_date,
num_interactions,
@runningTotal := @runningTotal + totals.num_interactions AS runningTotal
FROM
(SELECT
DATE(eDate) AS e_date,
COUNT(*) AS num_interactions
FROM example AS e
GROUP BY DATE(e.Date)) totals
ORDER BY e_date;
原答案
由于您的加入,您可能会得到重复。也许 e1 对某些行有多个匹配项,这会增加您的计数。无论是那个还是你的连接中的比较也是比较秒,这不是你所期望的。
无论如何,不要将日期时间字段分割成天和月,只需从中去掉时间即可。以下是你的做法。
SELECT
DATE(e.Date) AS e_date,
count(e.ID) AS num_interactions
FROM example AS e
JOIN example e1 ON DATE(e1.Date) <= DATE(e.Date)
GROUP BY DATE(e.Date);
【讨论】:
感谢您的回复。剥离时间是我想要做的。我仍然没有得到正确的结果,所以我认为这与加入有关。我想要的是,如果第一天的计数是 3,然后第二天是 4,那么它在第二天显示 7(前一天与当前的累积量)。在 DATE() screencast.com/t/qcsRcZt7Ws4z 加入时,计数仍然会膨胀... 2013-12-23 上只有 5 次互动 .. 所以我想我需要寻找一种不同的方式来实现这一点。 所以连接的问题在于它将每条记录与所有可能的记录匹配。又名.. 如果有 5 个实例,则它与 1 匹配所有 5,然后下一个与所有 5 匹配,因此计数膨胀为 25 而不是 5。关于如何解决此问题的任何想法? 抱歉,我不明白您是在计算运行总计。我将添加到我的答案中 这很棒,因为即使处理大型数据集也能很好地工作 很好的答案@clhereistian(该表只读取一次)!谢谢,对我帮助很大。提示:如果您使用的 ORM(如 php 中的 Doctrine)每次执行只能接受一个查询:在子查询中将SET @runningTotal = 0;
替换为 @runningTotal := 0,
:) (此提示还可以帮助您/我进行多- 查询之间使用 UNION 的累积和)以上是关于按日期分组的 MySQL 累积总和的主要内容,如果未能解决你的问题,请参考以下文章