在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游标