[英]getting the difference between two rows and perform mathematical operation on the difference mysql
例如,我的数据集如下所示
ID|Value
1|10
1|3
2|9
2|10
2|15
我需要找到相同 ID 的两个连续元素之间的差异并存储该值,然后再次找到差异并将存储的值与具有相同 ID 的所有值的新差异相乘。 这必须一直持续到有相同 ID 的元素。 因此我的最终数据集应该看起来像
ID|Value
1|-7
2|5
有没有人对我应该如何使用 sql 有任何建议
计算连续行之间的差异 -
MariaDB [sandbox]> SELECT T.*,
-> IF(T.TID <> @P ,@RN:=1,@RN:=@RN+1) RN,
-> IF(T.TID <> @P ,0, @PVAL) PVAL,
-> IF(T.TID <> @P ,0, T.VALUE * 1.00 - @PVAL) DIFF,
-> @P:=T.TID,
-> @PVAL:=T.VALUE
-> FROM(SELECT @RN:=0,@P:=0,@PVAL:=0.00,@DIFF:=0.00) RN,T
-> ORDER BY T.TID,T.dt;
+------------+------+-------+------+------+------+-----------+----------------+
| dt | TID | Value | RN | PVAL | DIFF | @P:=T.TID | @PVAL:=T.VALUE |
+------------+------+-------+------+------+------+-----------+----------------+
| 2017-01-01 | 1 | 10 | 1 | 0 | 0 | 1 | 10 |
| 2017-01-02 | 1 | 3 | 2 | 10 | -7 | 1 | 3 |
| 2017-01-01 | 2 | 9 | 1 | 0 | 0 | 2 | 9 |
| 2017-01-02 | 2 | 10 | 2 | 9 | 1 | 2 | 10 |
| 2017-01-03 | 2 | 15 | 3 | 10 | 5 | 2 | 15 |
+------------+------+-------+------+------+------+-----------+----------------+
5 rows in set (0.00 sec)
但是在 sql(据我所知的任何版本)中没有聚合函数可以计算差异的乘积(如果这是正确的词)。 更重要的是,您似乎想为每个 tid 丢弃第一行。 您可以通过 group_concatenating 差异到一个表中,然后调用一个存储过程来启动对动态 sql 的调用(顺便说一下,您不能在存储函数中使用动态 sql)。
这个存储过程
drop procedure if exists f;
delimiter //
CREATE DEFINER=`root`@`localhost` procedure `F`(
instring varchar(200)
)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
begin
declare tempstring varchar(100);
declare outstring varchar(100);
declare tempid int;
declare checkit int;
declare maxrecs int;
set checkit = 0;
set maxrecs = (select count(*) from temp);
looper: while checkit < maxrecs do
select tid,calc into tempid,tempstring from temp limit checkit,1;
set checkit = checkit + 1;
if instr(tempstring,',') = 0 then
update temp
set rsult = tempstring;
else
set outstring = replace(tempstring,',','*');
set outstring = concat('update temp set rsult = (Select ',outstring,') where tid = ', tempid, ';');
set @sqlstmt = outstring;
#select checkit, maxrecs, outstring;
prepare sqlstmt from @sqlstmt;
execute sqlstmt;
deallocate prepare sqlstmt;
end if;
end while;
end //
delimiter ;
在此脚本中调用时会产生您想要的结果
*ariaDB [sandbox]> drop table if exists temp;
Query OK, 0 rows affected (0.09 sec)
MariaDB [sandbox]> create table temp as
-> select s.tid,group_concat(s.diff) calc, 1.00 as rsult
-> from
-> (
-> SELECT T.*,
-> IF(T.TID <> @P ,@RN:=1,@RN:=@RN+1) RN,
-> IF(T.TID <> @P ,0, @PVAL) PVAL,
-> IF(T.TID <> @P ,0, T.VALUE * 1.00 - @PVAL) DIFF,
-> @P:=T.TID,
-> @PVAL:=T.VALUE
-> FROM(SELECT @RN:=0,@P:=0,@PVAL:=0.00,@DIFF:=0.00) RN,T
-> ORDER BY T.TID,T.dt
-> ) s
-> where s.rn <> 1
-> group by s.tid;
Query OK, 2 rows affected (0.23 sec)
Records: 2 Duplicates: 0 Warnings: 0
MariaDB [sandbox]>
MariaDB [sandbox]>
MariaDB [sandbox]> call f('1');
Query OK, 0 rows affected (0.07 sec)
MariaDB [sandbox]>
MariaDB [sandbox]> select * from temp;
+------+-----------+-------+
| tid | calc | rsult |
+------+-----------+-------+
| 1 | -7.00 | -7.00 |
| 2 | 1.00,5.00 | 5.00 |
+------+-----------+-------+
2 rows in set (0.00 sec)*
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.