Mysql 计算SQL中两行之间的差异

Mysql 计算SQL中两行之间的差异,mysql,Mysql,我有一个SQL表,一行是特定日期的收入,我想在表中添加一个新列,值是特定日期和前一天之间的增量可能是正收入或负收入,我想知道如何通过SQL实现 举个例子, 原始表格 ... Day1 100 Day2 200 Day3 150 ... 新表在末尾添加增量列,对于第一列,可以指定零 Day1 100 0 Day2 200 100 Day3 150 -50 我正在使用MySQL/MySQL工作台 提前感谢,, 林 查询假设每天表中有一条记录。如果每天的行数可能超过1行,则需要创建一个按天分组汇总

我有一个SQL表,一行是特定日期的收入,我想在表中添加一个新列,值是特定日期和前一天之间的增量可能是正收入或负收入,我想知道如何通过SQL实现

举个例子,

原始表格

...
Day1 100
Day2 200
Day3 150
...
新表在末尾添加增量列,对于第一列,可以指定零

Day1 100 0
Day2 200 100
Day3 150 -50
我正在使用MySQL/MySQL工作台

提前感谢,, 林

查询假设每天表中有一条记录。如果每天的行数可能超过1行,则需要创建一个按天分组汇总所有天的视图。

尝试

select 
    t.date_col, t.val_col,
    case when t1.val_col is null then 0
    else t.val_col - t1.val_col end diff
from (
    select t.* , @r := @r + 1 lev
    from tbl t,
    (select @r := 0) r
    order by t.date_col
) t
left join (
    select t.* , @r1 := @r1 + 1 lev
    from tbl t,
    (select @r1 := 1) r
    order by t.date_col 
) t1
on t.lev = t1.lev

即使缺少日期,这也会计算值diff。如果您可以稍微重新排序列,类似这样的内容很容易理解:

SET @prev := 0;
SELECT day, revenue - @prev AS diff, @prev := revenue AS revenue
FROM revenue ORDER BY day ASC;
诀窍是我们首先计算与上一个的差异,然后将上一个设置为当前,并在一步中将其显示为当前


注意,这取决于顺序是否正确,因为计算是在返回行的过程中完成的,所以您需要确保有一个order BY子句以正确的顺序返回天数。

您可能需要模拟超前或滞后函数:您的表是否有主键或唯一键列。@Praveen,是,有一个自动递增的整数事务ID列,为了简单起见,我在问题中忽略了它。如有任何建议,我们将不胜感激不,它是同一个表,a和b只是允许自连接的两个不同别名。表a和表b是同一个表。表连接自身:。a和b只是同一个表的别名。将“表”替换为DailyRevenue您的表名作为旁白,这种方法假设日期是数字的,并且是连续的,没有间隔。它也将无法打印第一天或最后一天不确定是哪一天,我头痛,所以不是最好的时间来尝试看看边缘案件!如果日期是datetime,则只需使用dateadd函数,假定所有日期的时间都相同。关于边缘情况,只有一个:表b中最后一行不匹配。在这种情况下,left join将在b.revenue中返回null,因此使用COALESCEb.revenue,0。您在哪里指定@r作为列revenue的值?谢谢。它只是作为排号。。对于第一个子查询,从1开始;对于第二个子查询,从2开始;像@r=@r2这样加入它们将有助于t.val\u col-t1.val\u col求值,其中`t1.val\u col`指向t.val\u colHi Praveen的下一个col,愚蠢的问题,为什么要在查询本身的顺序选择中编写赋值语句select@r1:=1r?这就是在MySQL中初始化@r1=进行比较的地方,所以我们需要:=to do assignment,否则@prev=revenue将返回0或1,这取决于它是否匹配。我可能还应该添加一个简短的警告,说明如何在同一语句中设置和读取变量,因为从技术上讲,顺序是未定义的。如果您真的想安全地执行此操作,最好的方法是在您的代码中读取返回的查询结果。对不起,我的意思是,如果您正在寻找一种更稳定的方法来执行此操作,您应该只让查询返回日期和数量,然后使用PHP或C或您正在使用的任何编程语言,让它在迭代从mysql库返回的结果集时计算与前一天的差值。两者都同意:我想我说的是,上面的方法至少已经运行了十年,我看不出有什么原因会突然失效,但是,您只需仔细了解上述操作的具体方式和原因,以及如何构造查询的限制。例如,添加引用其中包含变量的两列中任何一列的语句可能会中断查询。最好的方法是在应用程序中,而不是在SQL中。如果出于某种原因必须在SQL中执行此操作,唯一安全的方法是执行定义良好的自连接。这依赖于连接键的正确顺序,因此始终存在prev匹配,并且您需要考虑在连接条件中没有prev day的第一天要做什么-可能是一个左连接,在差分列中使用条件逻辑来处理null。当然,这使得在一天的序列中没有间隔的要求更加重要。
SET @prev := 0;
SELECT day, revenue - @prev AS diff, @prev := revenue AS revenue
FROM revenue ORDER BY day ASC;