计算前一行值的增加/减少百分比

时间:2015-05-27 13:45:42

标签: mysql sql

我有一张看起来像这样的表:

|date_start  | date_end    |amount | 
+------------+-------------+-------+
|2015-02-23  | 2015-03-01  |50     |
|2015-03-02  | 2015-03-08  |50     |
|2015-03-09  | 2015-03-15  |100    |
|2015-03-16  | 2015-03-22  |800    |
|2015-03-23  | 2015-03-29  |50     |

我想从上一个日期算出列amount的增加/减少百分比。例如,结果将是这样的,

|date_start  | date_end    |amount | perc_change | 
+------------+-------------+-------+-------------+
|2015-02-23  | 2015-03-01  |50     | 
|2015-03-02  | 2015-03-08  |50     | 0
|2015-03-09  | 2015-03-15  |100    | 50
|2015-03-16  | 2015-03-22  |800    | 700
|2015-03-23  | 2015-03-29  |50     | -750

我现在已经搜索并绞尽脑汁待了几天。通常,我只是使用服务器端代码执行此操作,但现在我需要在查询中包含所有内容。

5 个答案:

答案 0 :(得分:3)

如果我们假设前一行总是在当前开始前一天结束(如示例数据中那样),那么您可以使用join。增加的百分比是:

select t.*,
       100 * (t.amount - tprev.amount) / tprev.amount
from atable t left join
     atable tprev
     on tprev.date_end = t.date_start - interval 1 day;

然而,您的结果似乎只有差异,这更容易计算:

select t.*,
       (t.amount - tprev.amount) as diff
from atable t left join
     atable tprev
     on tprev.date_end = t.date_start - interval 1 day;

答案 1 :(得分:3)

试试这个:

 SELECT t.*,
 amount - (SELECT amount FROM transactions prev WHERE prev.date_end     < t.date_start ORDER BY date_start DESC LIMIT 1) AS changes
 FROM   transactions t

答案 2 :(得分:0)

它看起来像这样,我没有环境来测试这个选择,但我认为它应该工作

    SELECT t1.date_start, t1.date_end, t1.amount, (t1.amount - t2.amount)  as  perc_change
    FROM table1 t1 
      JOIN table1 t2  ON t1.id = t2.id + 1 // here your join to 
   //get next row and calculate this perc_change field

答案 3 :(得分:0)

我开始将表格中的每一行加到后面的那一行,如下所示:

SELECT m.date_start AS mStart, mt.date_start AS mtStart
FROM myTable m
JOIN myTable mT ON m.date_start < mt.date_start AND mt.date_start = (SELECT MIN(date_start) FROM myTable WHERE date_start > m.date_start);

这将连接表,以便每个行都可以看到以下日期(如果有的话)。如果没有,则不返回日期。

获得这些值后,您可以调整SELECT查询以显示之前日期的百分比变化,如下所示:

SELECT 
  mT.date_start AS secondDate, 
  mT.amount - m.amount AS percentChange
FROM myTable m
JOIN myTable mT ON m.date_start < mT.date_start AND mt.date_start = (SELECT MIN(date_start) FROM myTable WHERE date_start > m.date_start);

我想在这里做一个说明,虽然你说的是差异百分比&#39;在您的问题中,您的预期结果与百分比无关,而只是价值差异。如果您需要以不同的方式计算,可以调整上面的选择查询以满足您的需求。

您需要做的最后一件事就是将其重新连接到原始表格以查看所有值。这必须使用左连接来完成,以便可以看到表的第一个日期。这是最终查询:

SELECT m.date_start, m.date_end, m.amount, tmp.percentChange
FROM myTable m
LEFT JOIN(
  SELECT 
    mT.date_start AS secondDate, 
    mT.amount - m.amount AS percentChange
  FROM myTable m
  JOIN myTable mT ON m.date_start < mT.date_start AND mt.date_start = (SELECT MIN(date_start) FROM myTable WHERE date_start > m.date_start)
) tmp ON tmp.secondDate = m.date_start;

这是一个SQL Fiddle示例。

答案 4 :(得分:0)

你的情况是使用mysql var系统:

SELECT date_start, date_end, IF(@last IS NOT NULL,ammount - @last , '' ) as perc_change, @last := amount as amount 
From table 
ORDER BY date_start; 

var @last在每个段落设置,因此perc_change和amount之间的列顺序很重要