从多个递增序列中选择最大值的总和

时间:2016-07-06 16:11:05

标签: mysql sql

我想根据增量值序列计算最大值的总和。

此数据集:

time_stamp count
1467820429  6 *
1467820428  5
1467820427  4
1467820426  3
1467820416  2
1467820415  1
1467820413  0
1467820412  3 *
1467820411  2
1467820409  1
1467820408  0
1467820405  1 *
1467820404  0
1467820400  5 *

回答= 6 + 3 + 1 + 5 = 15

我如何编写MySQL兼容的SQL语句来实现这个

6 个答案:

答案 0 :(得分:1)

你可以通过以下方法获得它

mysql> select time_stamp,count,if (count=0,@curRank :=0,@curRank := @curRank + 1) as rank from ff,(SELECT @curRank := 0) r;
+------------+-------+------+
| time_stamp | count | rank |
+------------+-------+------+
| 1467820429 |     6 |    1 |
| 1467820428 |     5 |    2 |
| 1467820427 |     4 |    3 |
| 1467820426 |     3 |    4 |
| 1467820415 |     2 |    5 |
| 1467820415 |     1 |    6 |
| 1467820413 |     0 |    0 |
| 1467820412 |     3 |    1 |
| 1467820411 |     2 |    2 |
| 1467820409 |     1 |    3 |
| 1467820408 |     0 |    0 |
| 1467820405 |     1 |    1 |
| 1467820404 |     0 |    0 |
| 1467820408 |     5 |    1 |
+------------+-------+------+
14 rows in set (0.00 sec)

mysql> SELECT * FROM (select time_stamp,count,if (count=0,@curRank :=0,@curRank := @curRank + 1) as rank from ff,(SELECT @curRank := 0) r) t WHERE rank=1;
+------------+-------+------+
| time_stamp | count | rank |
+------------+-------+------+
| 1467820408 |     5 |    1 |
| 1467820412 |     3 |    1 |
| 1467820429 |     6 |    1 |
| 1467820405 |     1 |    1 |
+------------+-------+------+
4 rows in set (0.00 sec)

    mysql> SELECT sum(count) as total FROM 
(select time_stamp,count,if (count=0,@curRank :=0,@curRank := @curRank + 1) as rank from ff,
(SELECT @curRank := 0) r) t WHERE rank=1;
    +-------+
    | total |
    +-------+
    |    15 |
    +-------+
    1 row in set (0.00 sec)

你可以通过简单的内部查询获得它

答案 1 :(得分:1)

正如我在评论中所提到的,至少在Mysql至少根据我的知识这样做没有有效的方法

试试这个

SELECT Sum(CASE 
             WHEN `count` >= prev_cnt THEN `count` 
             ELSE 0 
           END) 
FROM   (SELECT *, 
               IFnull((SELECT `count` 
                       FROM   yourtable b 
                       WHERE  a.`time_stamp` < b.`time_stamp` 
                       ORDER  BY `time_stamp` LIMIT 1), `count`) AS prev_cnt 
        FROM   yourtable a) c 

答案 2 :(得分:0)

您需要确定值何时发生变化。获取前一个值的一种方法是使用变量:

select sum(count)
from (select t.*,
             (if((@old_c := @c) is null, 0, -- never happens
                 if((@c := count) is not null, @old_c, @old_c)
                )
             ) as prev_count
      from t cross join
           (select @c := -1) params
      order by time_stamp
     ) t
where prev_count >= count;

获取先前计数的表达式有点复杂。 MySQL不保证表达式的评估顺序,因此count的新值的赋值和返回旧值需要在单个表达式中。

答案 3 :(得分:0)

SELECT SUM(a.cnt)
  FROM 
     ( SELECT x.*
            , MIN(y.time_stamp) next
         FROM my_table x
         LEFT
         JOIN my_table y
           ON y.time_stamp > x.time_stamp
        GROUP 
           BY x.time_stamp
     ) a
  LEFT
  JOIN my_table b
    ON b.time_stamp = a.next
   AND b.cnt > a.cnt
 WHERE b.cnt IS NULL;

答案 4 :(得分:-1)

您需要GROUP BY和HAVING,如下所示:

select sum ( count ) 
from table
group by time_stamp
having count = max(count)

答案 5 :(得分:-2)

非常简单的解决方案:     1-取列time_stamp

的滞后
2- take the difference of orif time_stamp column and the lag column 

3- sum the values of count after filtering out the records for -1 

    +------------+-------+------+-----------------+-------+
| a          | b     | c    | d               | a-d   |
| time_stamp | count | flag | lag_time_stamp  | diff  |
| 1467820429 | 6     | *    | nulll           | null  |
| 1467820428 | 5     |      | 1467820429      | -1    |
| 1467820427 | 4     |      | 1467820428      | -1    |
| 1467820426 | 3     |      | 1467820427      | -1    |
| 1467820416 | 2     | *    | 1467820426      | -10   |
| 1467820415 | 1     |      | 1467820416      | -1    |
| 1467820413 | 3     | *    | 1467820415      | -2    |
| 1467820412 | 3     |      | 1467820413      | -1    |
| 1467820411 | 2     |      | 1467820412      | -1    |
| 1467820409 | 1     | *    | 1467820411      | -2    |
| 1467820408 | 0     |      | 1467820409      | -1    |
| 1467820405 | 1     | *    | 1467820408      | -3    |
| 1467820404 | 0     |      | 1467820405      | -1    |
| 1467820400 | 5     | *    | 1467820404      | -4    |
+------------+-------+------+-----------------+-------+

--sum the values of the table that we got after filtering the records for -1

+------------+-------+
| time_stamp | count |
+------------+-------+
| 1467820429 |     6 |
| 1467820416 |     2 |
| 1467820413 |     3 |
| 1467820409 |     1 |
| 1467820405 |     1 |
| 1467820400 |     5 |
+------------+-------+