【问题标题】:Calculating cumulative values for every 12 months on tables with possibly null values在可能为空值的表上计算每 12 个月的累积值
【发布时间】:2017-08-26 03:31:04
【问题描述】:

我有这张桌子:

Month       Year         MV                    MI         fullDate
-----------------------------------------------------------------
...
5           2015         1                      5         2015-05-01
6           2015         1                     10         2015-06-01
7           2015         3                     10         2015-07-01
8           2015         2                     10         2015-08-01
11          2015         1                     10         2015-11-01
1           2016         4                     10         2016-01-01
6           2016         1                     20         2016-06-01
7           2016         null                  10         2016-07-01
8           2016         2                      5         2016-08-01
...

我需要创建另一个具有累积值的表:

Month       Year         AMV                  AMI
-----------------------------------------------------------------
...    
7           2015         3                     10
8           2015         5                     20
11          2015         6                     30
1           2016         10                    40
6           2016         11                    60
7           2016         0                     10
8           2016         2                     15
...

累计计算必须从 7 月开始,到次年 6 月结束。在此示例中,累积字段从 2015 年 7 月开始“累积”并于 2016 年 6 月结束。这些计算在 2016 年 7 月重新开始,累积值的另一个周期“计算”

我之前也提出过类似的问题,但我刚刚发现了这种用于累积计算的“周期性”。还有一件事……第一个表上的某些值可能为空,需要被视为 0。

请告诉我如何做到这一点?

【问题讨论】:

  • 您能解释一下 AMV 和 AMI 是如何计算的吗?
  • 对于 2015 年第 7 个月,MV 为 3,因此 AMV 为 3。对于 2015 年第 8 个月,MV 为 2,因此 AMV 为 2+3 = 5,依此类推,直到明年 6 月。

标签: mysql date null sum


【解决方案1】:

这就是诀窍:

SET @amv := 0, @ami := 0;

SELECT 
  (@amv:=IF(ISNULL(MV), 0, @amv+MV)) as AMV, 
  (@ami:=IF(ISNULL(MI), 0, @ami+MI)) as AMI, 
  fullDate
FROM 
  input
WHERE 
  fullDate >= "2015-07-01" AND
  fullDate < "2016-07-01"
ORDER BY fullDate ASC;

【讨论】:

  • 问题是我们预计 2016-07-01 之后会有更多的条目,我们需要重新计算从 Y 年 7 月到 6 月 (Y+1) 的累积值跨度>
  • 问题出在哪里?每次获得新值时只需重新运行查询。您可以截断表格并重新填充它,或者将@amv, @ami 设置为该表格的最后一个值。如果你想创建一个视图,那么我想这会变得复杂。
  • 好吧,也许这就是复杂性......他们想在一张大表中查看所有这些累积值
  • 好吧,你想念插入吗?只需在 select 前面添加 INSERT INTO table 即可获得 INSERT SELECT 语句。见 [dev.mysql.com/doc/refman/5.7/en/insert-select.html]
【解决方案2】:

我已经修改了来自@Sebastian 的查询。 init 也在查询中。计数器每年都会重置,而 where 不是必需的

SELECT 
  (@amv:=IF(MONTH(fulldate)=7,MV, IF(ISNULL(MV), 0, @amv+MV))) AS AMV, 
  (@ami:=IF(MONTH(fulldate)=7,MI, IF(ISNULL(MI), 0, @ami+MI))) AS AMI, 
  fullDate
FROM 
  input
CROSS JOIN ( SELECT @amv := 0, @ami := 0) AS init
ORDER BY fullDate ASC;

样本

mysql> select * from input;
+----+------+------+------------+
| id | MV   | MI   | fullDate   |
+----+------+------+------------+
|  1 |    1 |   10 | 2015-08-01 |
|  2 |    2 |   20 | 2015-09-01 |
|  3 |    3 |   30 | 2015-07-01 |
|  4 |    8 |   33 | 2016-07-01 |
|  5 |    2 |    8 | 2016-08-01 |
+----+------+------+------------+
5 rows in set (0,00 sec)

mysql>     SELECT
    ->       (@amv:=IF(MONTH(fulldate)=7,MV, IF(ISNULL(MV), 0, @amv+MV))) AS AMV,
    ->       (@ami:=IF(MONTH(fulldate)=7,MI, IF(ISNULL(MI), 0, @ami+MI))) AS AMI,
    ->       fullDate
    ->     FROM
    ->       input
    ->     CROSS JOIN ( SELECT @amv := 0, @ami := 0) AS init
    ->     ORDER BY fullDate ASC;
+------+------+------------+
| AMV  | AMI  | fullDate   |
+------+------+------------+
|    3 |   30 | 2015-07-01 |
|    4 |   40 | 2015-08-01 |
|    6 |   60 | 2015-09-01 |
|    8 |   33 | 2016-07-01 |
|   10 |   41 | 2016-08-01 |
+------+------+------------+
5 rows in set (0,00 sec)

mysql>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-06
    • 2022-01-17
    • 2017-06-26
    • 1970-01-01
    • 1970-01-01
    • 2012-04-19
    • 1970-01-01
    相关资源
    最近更新 更多