MySQL上一行计算

MySQL上一行计算,mysql,Mysql,在MySQL查询中保存变量时遇到问题。我的表格很简单: +--------------+-------------+ | SUM(price) | timestamp | +--------------+-------------+ |433 |2015-05-02 | +--------------+-------------+ |498 |2015-06-02 | +--------------+-------------+ |440

在MySQL查询中保存变量时遇到问题。我的表格很简单:

+--------------+-------------+
|  SUM(price)  |  timestamp  |
+--------------+-------------+
|433           |2015-05-02   |
+--------------+-------------+
|498           |2015-06-02   |
+--------------+-------------+
|440           |2015-06-04   |
+--------------+-------------+
|434           |2015-06-07   |
+--------------+-------------+
|433           |2015-06-09   |
+--------------+-------------+
请注意,时间戳不是每日/每月,并且没有索引。上表是以下查询的结果:

选择SUM(price)作为totalvalue,timestamp作为ts,basetable GROUP BY timestamp ORDER BY timestamp ASC
这将生成一个日期列表(timestamp),其中包含该特定时间戳中所有价格的总和。(因此,“分组依据”和“排序依据”是指年代表)

我需要的是当前行的总数和它前面的行之间的差值,如下所示:

+--------------+-------------+--------+
|  SUM(price)  |  timestamp  |  diff  |
+--------------+-------------+--------+
|433           |2015-05-02   |0       |
+--------------+-------------+--------+
|498           |2015-06-02   |65      |
+--------------+-------------+--------+
|440           |2015-06-04   |-58     |
+--------------+-------------+--------+
|434           |2015-06-07   |-6      |
+--------------+-------------+--------+
|433           |2015-06-09   |-1      |
+--------------+-------------+--------+
diff列所做的就是
当前行总计-上一行总计
。(第一行为0)我尝试将当前行的总数保存在@变量中,并在下一行检索它,但无法使其工作

解决方案可能很简单,但我似乎无法得到它

更新:我尝试过(但失败了)这些方法:

选择SUM(a.price)作为totalvalue,a.timestamp,SUM(a.price)-COALESCE(SUM(b.price),0)作为前一行
从基表a
a上的左联接基表b.timestamp=b.timestamp-1

SET@prev:=0;
选择时间戳、总和(价格)、总和(价格)-@prev作为diff、@prev:=总和(价格)作为diff 2
按时间戳ASC从基表顺序


这两个数据库都来自这个网站,因为我不知道如何让它工作…

大多数其他数据库都支持
LAG()
,这使得这更容易。我们可以使用变量在MySQL中模拟这一点:

SELECT totalvalue, ts,
       (CASE WHEN (@save_prev := prev) = NULL THEN NULL  -- = NULL is *never* true
             WHEN (@prev := totalvalue) = NULL THEN NULL -- = NULL is *never* true
             ELSE @save_prev
        END) as prev_value
FROM (SELECT SUM(price) AS totalvalue, timestamp AS ts
      FROM basetable 
      GROUP BY timestamp
     ) t CROSS JOIN
     (SELECT @prev := 0) params
ORDER BY timestamp ASC;
因此,获得差异很容易:

SELECT totalvalue, ts,
       (totalvalue -
        (CASE WHEN (@save_prev := prev) = NULL THEN NULL  -- = NULL is *never* true
              WHEN (@prev := totalvalue) = NULL THEN NULL -- = NULL is *never* true
              ELSE @save_prev
         END)
        ) as diff
FROM (SELECT SUM(price) AS totalvalue, timestamp AS ts
      FROM basetable 
      GROUP BY timestamp
     ) t CROSS JOIN
     (SELECT @prev := 0) params
ORDER BY timestamp ASC;
注意:变量的使用很棘手。MySQL不保证
SELECT
中表达式的求值顺序。因此,所有相关变量的计算都需要在同一个表达式中


上面使用了对
案例
条件的顺序评估来确保这一点。
=NULL
有意识地被用作总是返回false的东西(实际上
和false
和1=0
会做同样的事情)。这确保了变量值的计算顺序正确。

显示您的尝试?否则我们怎么能告诉你你做错了什么呢?大卫将来会创作一幅提琴画。SQLFiddle目前对我来说已经过时了(并没有构建或查询,即使有了示例),这就是为什么并没有fiddle的原因。我可以的时候再加一个