在MySQL中计算一个正在运行的总数

我有这个MySQL查询:

SELECT DAYOFYEAR(`date`) AS d, COUNT(*) FROM `orders` WHERE `hasPaid` > 0 GROUP BY d ORDER BY d 

其中返回这样的东西:

 d | COUNT(*) | 20 | 5 | 21 | 7 | 22 | 12 | 23 | 4 | 

我真的很喜欢的是另一列结束显示运行总数:

 d | COUNT(*) | ??? | 20 | 5 | 5 | 21 | 7 | 12 | 22 | 12 | 24 | 23 | 4 | 28 | 

这可能吗?

也许是一个更简单的解决scheme,并防止数据库不得不做大量的查询。 这只执行一个查询,然后对结果进行一次math计算。

 SET @runtot:=0; SELECT q1.d, q1.c, (@runtot := @runtot + q1.c) AS rt FROM (SELECT DAYOFYEAR(`date`) AS d, COUNT(*) AS c FROM `orders` WHERE `hasPaid` > 0 GROUP BY d ORDER BY d) AS q1 

这会给你一个额外的RT(总运行)列。 不要错过上面的SET语句来初始化运行的总variables,否则你只会得到一列NULL值。

 SELECT DAYOFYEAR(O.`date`) AS d, COUNT(*), (select count(*) from `orders` where DAYOFYEAR(`date`) <= d and `hasPaid` > 0) FROM `orders` as O WHERE O.`hasPaid` > 0 GROUP BY d ORDER BY d 

这将需要一些语法调整(我没有MySQL来testing它),但它显示了你的想法。 子查询只需要返回并添加已经包含在外部查询中的新鲜事物,而且必须为每一行都做到这一点。

看看这个问题如何使用连接来完成相同的。

为了解决数据增长对性能下降的担忧: 一年366天,假设你没有多年运行这个查询,子查询将被评估到366次。 在date和hasPaid标志的正确索引,你会没事的。

我会说,这是不可能的,每一个产生的行应该是独立的。 使用编程语言获取这些值

除非你没有别的select,只是在sql中这样做,我会把结果以编程语言进行求和。 随着桌子的增长,这样的嵌套将变得非常慢。

你可以使用Cross Join语句或者一些slef连接来破解这个,但是对于任何大型的数据集来说,它会变得很慢,所以最好在后置查询处理器中完成。 在客户端代码中的任一游标

这是游标比基于集合的查询更快的唯一地方之一,如果性能是至关重要的我会

  • 在MySql之外做这个
  • 使用MySql 5游标