【问题标题】:fetching cumulative sum grouped by month on time interval获取按时间间隔按月分组的累积总和
【发布时间】:2015-10-05 09:16:33
【问题描述】:

这是用户表。我从哪里获取数据并通过将表 d 添加到查询来填写缺失的月份。

---------------------------------------
|   uid   |       date_register        |
---------------------------------------
| 1       |      2011-07-20 02:24:36   |
---------------------------------------
| 2       |      2012-10-03 07:37:43   |
---------------------------------------
|   ...   |      ... ... ... ... ...   |
---------------------------------------
| 300000  |      2015-12-19 04:13:51   |
---------------------------------------

我想获取按月分组的累积总和。我正在使用以下查询来执行此操作。

SELECT d.y, d.m, p.cum_sum 
            FROM 
            (SELECT a.y, b.m 
            FROM (SELECT 2015 AS Y UNION ALL SELECT 2014 AS Y) a
            CROSS JOIN (SELECT 1 AS m UNION ALL SELECT 2 AS m UNION ALL SELECT 3 AS m UNION ALL SELECT 4 AS m UNION ALL SELECT 5 AS m UNION ALL SELECT 6 AS m UNION ALL SELECT 7 AS m UNION ALL SELECT 8 AS m UNION ALL SELECT 9 AS m UNION ALL SELECT 10 AS m UNION ALL SELECT 11 AS m UNION ALL SELECT 12 AS m) b
            WHERE CONCAT(a.y, '-', b.m, '-01') BETWEEN CURDATE() - INTERVAL 13 MONTH AND CURDATE()
            ORDER BY 1, 2) d
            LEFT OUTER JOIN
            (SELECT year1,
                    month, 
                    @cnt := @cnt + total cum_sum
  FROM (
        SELECT YEAR(date_register) year1,
               MONTH(date_register) month,
               COUNT(*) total
               FROM users
               WHERE date_register >= DATE_FORMAT(NOW() ,'%Y-%m-01') - INTERVAL 1 YEAR
               AND useractivated = 1
               GROUP BY YEAR(date_register), MONTH(date_register)
       ) n, (SELECT @cnt := count(*) from users
 where date_register< DATE_FORMAT(NOW() ,'%Y-%m-01') - INTERVAL 1 YEAR AND useractivated = 1) u)
            p ON d.m=p.month AND d.y=p.year1
            ORDER BY 1 ASC, 2 ASC

但如果该特定月份没有交易,则返回空值。如下(示例数据)

+------+-------+---------+
|   y  |   m   | cum_sum |
+------+-------+---------+
| 2014 |   10  |  12356  |
| 2014 |   11  |  13567  |
| 2014 |   12  |  14239  |
| 2015 |   01  |  15234  |
| 2015 |   02  |  16571  |
| 2015 |   03  |   NULL  |
| 2015 |   04  |  24239  |
| 2015 |   05  |  34239  |
| 2015 |   06  |  44239  |
| 2015 |   07  |  45239  |
| 2015 |   08  |  46239  |
| 2015 |   09  |  57239  |
| 2015 |   10  |  67239  |
+------+-------+---------+

所以 2015 年 3 月没有交易,所以它返回 null 但它应该像上一行一样返回 16571。我做错了什么?谢谢。

【问题讨论】:

  • 这里有很多查询。

标签: mysql cross-join


【解决方案1】:

试试这个:

    select a.y, b.m, 
         (
          SELECT count(*) as cum_count
          FROM users
          WHERE (YEAR(date_register) = a.y and MONTH(date_register) <= b.m) or year(date_register) < a.y
         ) as cum_count 
    from
    (
    SELECT 2015 AS Y UNION ALL SELECT 2014 AS Y
    ) a
    CROSS JOIN 
    (
    SELECT 1 AS m UNION ALL SELECT 2 AS m UNION ALL SELECT 3 AS m UNION ALL SELECT 4 AS m UNION ALL SELECT 5 AS m UNION ALL SELECT 6 AS m UNION ALL SELECT 7 AS m UNION ALL SELECT 8 AS m UNION ALL SELECT 9 AS m UNION ALL SELECT 10 AS m UNION ALL SELECT 11 AS m UNION ALL SELECT 12 AS m
    ) b
    order by a.y, b.m

【讨论】:

  • 你能设置一个 sql fiddle 吗?如果是这样,我会积极帮助您找到解决方案。谢谢!
  • 嘿@Mihai Ovidiu Drăgoi 运气好吗?
  • 这真的让我发疯了:D 我简化了很多语法,但仍然没有雪茄。
  • 我不能告诉你我必须做什么来验证它是否有效。长话短说,它不适用于 SQLFiddle,但是 .. 它有效 :) 已编辑答案。希望它也对你有用!
  • 它可以工作,但是你删除了很多东西,它需要 26-28 秒才能运行 .. 前一个需要不到一秒。顺便说一句,感谢您的帮助。 :)
猜你喜欢
  • 1970-01-01
  • 2014-07-13
  • 2020-04-10
  • 2015-09-11
  • 1970-01-01
  • 1970-01-01
  • 2014-04-12
  • 2021-11-17
  • 2015-12-08
相关资源
最近更新 更多