【问题标题】:MySQL summary table - evaluate and adjustMySQL 汇总表 - 评估和调整
【发布时间】:2016-08-16 08:11:02
【问题描述】:

我有一个非常简单的汇总表,它汇总了表中的 2 个字段,其中每隔 15 分钟收集一次记录。所以;

SELECT timevalue, SUM(value1)  AS sumvalue1, SUM(value2) AS sumvalue2 
FROM table 
GROUP BY timevalue

返回我期望的结果;

timevalue        sumvalue1  sumvalue2
-------------------------------------
16/08/2016 08:30    3000      200
16/08/2016 08:45    3200      150
16/08/2016 09:00    3100      400
16/08/2016 09:15    3300      450
16/08/2016 09:30    3400      600

我的问题是,有没有办法检查每个总和值永远不会小于前一个值?如果它返回前一个时间值的总和? (因此总和值总是等于或大于前一个时间值)。

结果表应如下所示;

timevalue        sumvalue1  sumvalue2
-------------------------------------
16/08/2016 08:30    3000      200
16/08/2016 08:45    3200      200
16/08/2016 09:00    3200      400
16/08/2016 09:15    3300      450
16/08/2016 09:30    3400      600

我猜我需要某种 if 语句?关于如何实现这一点的任何想法?

非常感谢

【问题讨论】:

    标签: mysql select sum


    【解决方案1】:

    您可以使用用户定义的变量来做到这一点,然后做一些算术运算

    select timevalue,sumvalue_1 as sumvalue1, sumvalue_2 as sumvalue2 from
    (
     select 
     timevalue,
     if(@prev_val1 = sumvalue1 or @prev_val1 > sumvalue1,@prev_val1,sumvalue1) as sumvalue_1,
     if(@prev_val2 = sumvalue2 or @prev_val2 > sumvalue2,@prev_val2,sumvalue2) as sumvalue_2,
     @prev_val1 := sumvalue1,
     @prev_val2 := sumvalue2
     from mytable,(select @prev_val1:=0,@prev_val2:=0)x
     order by timevalue
    )x
    order by timevalue 
    

    这是一个演示

    create table mytable (
     timevalue datetime,
     sumvalue1 int,
     sumvalue2 int
    );
    
    insert into mytable values 
    ('2016-08-16 08:30:00',3000,200),
    ('2016-08-16 08:45:00',3200,150),
    ('2016-08-16 09:00:00',3100,400),
    ('2016-08-16 09:15:00',3300,450),
    ('2016-08-16 09:30:00',3400,600);
    
    
    mysql> select * from mytable;
    +---------------------+-----------+-----------+
    | timevalue           | sumvalue1 | sumvalue2 |
    +---------------------+-----------+-----------+
    | 2016-08-16 08:30:00 |      3000 |       200 |
    | 2016-08-16 08:45:00 |      3200 |       150 |
    | 2016-08-16 09:00:00 |      3100 |       400 |
    | 2016-08-16 09:15:00 |      3300 |       450 |
    | 2016-08-16 09:30:00 |      3400 |       600 |
    +---------------------+-----------+-----------+
    

    现在查询

    mysql> select timevalue,sumvalue_1 as sumvalue1, sumvalue_2 as sumvalue2 from
        -> (
        ->  select 
        ->  timevalue,
        ->  if(@prev_val1 = sumvalue1 or @prev_val1 > sumvalue1,@prev_val1,sumvalue1) as sumvalue_1,
        ->  if(@prev_val2 = sumvalue2 or @prev_val2 > sumvalue2,@prev_val2,sumvalue2) as sumvalue_2,
        ->  @prev_val1 := sumvalue1,
        ->  @prev_val2 := sumvalue2
        ->  from mytable,(select @prev_val1:=0,@prev_val2:=0)x
        ->  order by timevalue
        -> )x
        -> order by timevalue;
    +---------------------+-----------+-----------+
    | timevalue           | sumvalue1 | sumvalue2 |
    +---------------------+-----------+-----------+
    | 2016-08-16 08:30:00 |      3000 |       200 |
    | 2016-08-16 08:45:00 |      3200 |       200 |
    | 2016-08-16 09:00:00 |      3200 |       400 |
    | 2016-08-16 09:15:00 |      3300 |       450 |
    | 2016-08-16 09:30:00 |      3400 |       600 |
    +---------------------+-----------+-----------+
    

    【讨论】:

    • 嗨 Abhik,演示效果很好,但是 sumvalue1 和 sumvalue 2 是计算字段。如果我将更多值添加到 mytable 中,然后尝试将 sumvalue1 和 sumvalue2 更改为 sum(sumvalue1) 和 sum(sumvalue2) 以及按时间值添加组,我只会得到实际计算的数字。不是调整后的数字……
    • select timevalue,sumvalue_1 as sumvalue1, sumvalue_2 as sumvalue2 from ( select timevalue, if(@prev_val1 = sum(sumvalue1) or @prev_val1 > sum(sumvalue1),@prev_val1,sum(sumvalue1)) as sumvalue_1, if(@prev_val2 = sum(sumvalue2) or @prev_val2 > sum(sumvalue2),@prev_val2,sum(sumvalue2)) as sumvalue_2, @prev_val1 := sum(sumvalue1), @prev_val2 := sum(sumvalue2) from mytable,(select @prev_val1:=0,@prev_val2:=0)x group by timevalue order by timevalue )x order by timevalue
    • 是的,您可以修改示例查询并将原始查询放置为内部查询,而不是 from mytable,您可以使用 `from (选择您的实际查询)x,(....)`
    • 试试select timevalue,sumvalue_1 as sumvalue1, sumvalue_2 as sumvalue2 from ( select timevalue, if(@prev_val1 = sumvalue1 or @prev_val1 > sumvalue1,@prev_val1,sumvalue1) as sumvalue_1, if(@prev_val2 = sumvalue2 or @prev_val2 > sumvalue2,@prev_val2,sumvalue2) as sumvalue_2, @prev_val1 := sumvalue1, @prev_val2 := sumvalue2 from ( SELECT timevalue, SUM(value1) AS sumvalue1, SUM(value2) AS sumvalue2 FROM table GROUP BY timevalue )y,(select @prev_val1:=0,@prev_val2:=0)x order by timevalue )x order by timevalue
    • 遗憾的是,毕竟不是 100% 工作。适用于 2 个连续下降的值,但是如果有 3 个连续值,则第三个值将根据第二个总和值而不是更新值(取自第一个值)进行评估。我希望这是有道理的?!
    【解决方案2】:

    不是最漂亮的例子,但仍然可以工作。

    INSERT INTO SecondTable VALUES (
      NOW(),
      GREATEST(
        YOUR_SUM_1, (SELECT sumvalue1 FROM FirstTable ORDER BY timevalue DESC LIMIT 1)
      ),
      GREATEST(
        YOUR_SUM_2, (SELECT sumvalue2 FROM FirstTable ORDER BY timevalue DESC LIMIT 1)
      )
     );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-10
      • 1970-01-01
      • 1970-01-01
      • 2018-07-25
      • 2016-12-25
      相关资源
      最近更新 更多