仅用一句SQL更新整张表的涨跌幅、涨跌率的解决方案

问题场景

各大平台店铺的三项评分(物流、服务、商品)变化情况;
商品每日价格的变化记录;
股票的实时涨跌浮;

复现场景

表:主键ID,商品编号,记录时的时间,记录时的价格,创建时间。
问题:获取每个商品每次的变化情况(涨跌幅、涨跌率)。

解决思路

1、要想高效率的更新涨跌,就肯定不能是逐条数据更新,要通过自连表建立起对应关系,将每一条数据关联到上一次的价格数据。

2、由于数据库非常庞大,所以可能存在很多垃圾数据,就比如说相关的字段值为NULL或者非有效值的,这些数据要先排除掉。

SELECT id,goods_code,goods_date,goods_price FROM test_goods_price_change WHERE goods_price IS NOT NULL AND goods_date IS NOT NULL;

3、然后在获取每条数据的上一条数据,同样也要先排除掉垃圾数据。

SELECT tmp_a.*, MAX(tmp_b.goods_date) AS last_date FROM
( SELECT id,goods_code,goods_date,goods_price FROM test_goods_price_change WHERE goods_price IS NOT NULL AND goods_date IS NOT NULL ) AS tmp_a
LEFT JOIN
( SELECT id,goods_code,goods_date,goods_price FROM test_goods_price_change WHERE goods_price IS NOT NULL AND goods_date IS NOT NULL ) AS tmp_b
ON tmp_a.goods_code = tmp_b.goods_code AND tmp_a.goods_date > tmp_b.goods_date GROUP BY tmp_a.id;

4、获取到上一条数据后,获取上条数据对应的商品价格。

SELECT tmp_ab.*,tmp_c.goods_price AS last_price FROM
(
	SELECT tmp_a.*, MAX(tmp_b.goods_date) AS last_date FROM
	( SELECT id,goods_code,goods_date,goods_price FROM test_goods_price_change WHERE goods_price IS NOT NULL AND goods_date IS NOT NULL ) AS tmp_a
	LEFT JOIN
	( SELECT id,goods_code,goods_date,goods_price FROM test_goods_price_change WHERE goods_price IS NOT NULL AND goods_date IS NOT NULL ) AS tmp_b
	ON tmp_a.goods_code = tmp_b.goods_code AND tmp_a.goods_date > tmp_b.goods_date GROUP BY tmp_a.id
) AS tmp_ab
LEFT JOIN (SELECT id,goods_code,goods_date,goods_price FROM test_goods_price_change WHERE goods_price IS NOT NULL AND goods_date IS NOT NULL ) AS tmp_c
ON tmp_ab.goods_code = tmp_c.goods_code AND tmp_c.goods_date = tmp_ab.last_date ORDER BY tmp_ab.id;

5、获取到上条数据以及对应的价格后,开始进行计算,获取到最终的结果。

SELECT
	*,
	(CONVERT(goods_price, DECIMAL(10,2)) - CONVERT(last_price, DECIMAL(10,2))) AS '涨跌幅',
	ROUND((CONVERT(goods_price, DECIMAL(10,2)) - CONVERT(last_price, DECIMAL(10,2)))/CONVERT(last_price, DECIMAL(10,2)), 2) AS '涨跌率'
FROM (
	SELECT tmp_ab.*,tmp_c.goods_price AS last_price FROM
	(
		SELECT tmp_a.*, MAX(tmp_b.goods_date) AS last_date FROM
		( SELECT id,goods_code,goods_date,goods_price FROM test_goods_price_change WHERE goods_price IS NOT NULL AND goods_date IS NOT NULL ) AS tmp_a
		LEFT JOIN
		( SELECT id,goods_code,goods_date,goods_price FROM test_goods_price_change WHERE goods_price IS NOT NULL AND goods_date IS NOT NULL ) AS tmp_b
		ON tmp_a.goods_code = tmp_b.goods_code AND tmp_a.goods_date > tmp_b.goods_date GROUP BY tmp_a.id
	) AS tmp_ab
	LEFT JOIN (SELECT id,goods_code,goods_date,goods_price FROM test_goods_price_change WHERE goods_price IS NOT NULL AND goods_date IS NOT NULL ) AS tmp_c
	ON tmp_ab.goods_code = tmp_c.goods_code AND tmp_c.goods_date = tmp_ab.last_date ORDER BY tmp_ab.id
) AS tmp

解决方案

-- 创建表SQL
CREATE TABLE `test_goods_price_change` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `goods_code` varchar(50) NOT NULL COMMENT '商品编码',
  `goods_date` int(11) NOT NULL COMMENT '记录时的时间',
  `goods_price` decimal(10,2) NOT NULL COMMENT '记录时的价格',
  `created_at` int(11) NOT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB CHARSET=utf8mb4;

-- 获取涨跌浮SQL
SELECT
	*,
	(CONVERT(goods_price, DECIMAL(10,2)) - CONVERT(last_price, DECIMAL(10,2))) AS '涨跌幅',
	ROUND((CONVERT(goods_price, DECIMAL(10,2)) - CONVERT(last_price, DECIMAL(10,2)))/CONVERT(last_price, DECIMAL(10,2)), 2) AS '涨跌率'
FROM (
	SELECT tmp_ab.*,tmp_c.goods_price AS last_price FROM
	(
		SELECT tmp_a.*, MAX(tmp_b.goods_date) AS last_date FROM
		( SELECT id,goods_code,goods_date,goods_price FROM test_goods_price_change WHERE goods_price IS NOT NULL AND goods_date IS NOT NULL ) AS tmp_a
		LEFT JOIN
		( SELECT id,goods_code,goods_date,goods_price FROM test_goods_price_change WHERE goods_price IS NOT NULL AND goods_date IS NOT NULL ) AS tmp_b
		ON tmp_a.goods_code = tmp_b.goods_code AND tmp_a.goods_date > tmp_b.goods_date GROUP BY tmp_a.id
	) AS tmp_ab
	LEFT JOIN (SELECT id,goods_code,goods_date,goods_price FROM test_goods_price_change WHERE goods_price IS NOT NULL AND goods_date IS NOT NULL ) AS tmp_c
	ON tmp_ab.goods_code = tmp_c.goods_code AND tmp_c.goods_date = tmp_ab.last_date ORDER BY tmp_ab.id
) AS tmp

到此这篇关于仅用一句SQL更新整张表的涨跌幅、涨跌率的文章就介绍到这了,更多相关SQL更新整张表内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 如何使用MySQL一个表中的字段更新另一个表中字段

    1,修改1列 update student s, city c set s.city_name = c.name where s.city_code = c.code; 2,修改多个列 update a, b set a.title=b.title, a.name=b.name where a.id=b.id •子查询 update student s set city_name = (select name from city where code = s.city_code); oracle

  • MySQL数据库同时查询更新同一张表的方法

    在平常的项目中,经常会碰到这样的问题:我需要在一张标中同时更新和查询出来的数据.例如:有如下图一张表数据,现在需要更新操作为:把status=1的name值更新为id=2的name值 通常情况下我们会想到如下语句来实现这个需求: UPDATE tb_testSET NAME = ( SELECT NAME FROM tb_test WHERE id= 2)WHERE `status` = 1 结果却报错,报错信息为:You can't specify target table 'tb_test'

  • mysql用一个表更新另一个表的方法

    Solution 1:  修改1列 update student s, city c set s.city_name = c.name where s.city_code = c.code; Solution 2:  修改多个列 update  a,  b set a.title=b.title, a.name=b.name where a.id=b.id Solution 3: 采用子查询 update student s set city_name = (select name from c

  • Mysql 根据一个表数据更新另一个表的某些字段(sql语句)

    下面一段代码给大家介绍Mysql 根据一个表数据更新另一个表的某些字段,具体代码如下所示: DROP TABLE IF EXISTS T_U_TEMPLATE; -- 模版表 CREATE TABLE T_U_TEMPLATE ( ID INT NOT NULL AUTO_INCREMENT comment '模版表ID', TEMPLATE_CODE VARCHAR(50) BINARY comment '模版编码', TEMPLATE_NAME VARCHAR(300) BINARY com

  • mysql实现查询数据并根据条件更新到另一张表的方法示例

    本文实例讲述了mysql实现查询数据并根据条件更新到另一张表的方法.分享给大家供大家参考,具体如下: 原本的数据库有3张表 travel_way :旅游线路表,存放线路的具体信息 traveltag :线路标签表,存放线路目的地等信息 tagrelation:标签对应表,存放线路和目的地的对应关系 因为业务逻辑的改变,现在要把它们合并为一张表,把traveltag中的目的地信息插入到travel_way中. 首先获取到所有线路对应的目的地,以线路ID分组,合并目的地到一行,以逗号分隔. 复制代码

  • Mysql update多表联合更新的方法小结

    下面我建两个表,并执行一系列sql语句,仔细观察sql执行后表中数据的变化,很容易就能理解多表联合更新的用法 student表 class表 1. 执行 UPDATE student s , class c SET s.class_name='test00',c.stu_name='test00' WHERE s.class_id = c.id student表 class表 2. 执行 UPDATE student s JOIN class c ON s.class_id = c.id SET

  • 仅用一句SQL更新整张表的涨跌幅、涨跌率的解决方案

    问题场景 各大平台店铺的三项评分(物流.服务.商品)变化情况: 商品每日价格的变化记录: 股票的实时涨跌浮: 复现场景 表:主键ID,商品编号,记录时的时间,记录时的价格,创建时间. 问题:获取每个商品每次的变化情况(涨跌幅.涨跌率). 解决思路 1.要想高效率的更新涨跌,就肯定不能是逐条数据更新,要通过自连表建立起对应关系,将每一条数据关联到上一次的价格数据. 2.由于数据库非常庞大,所以可能存在很多垃圾数据,就比如说相关的字段值为NULL或者非有效值的,这些数据要先排除掉. SELECT i

  • 一句sql更新两个表并可更新对应的字段值具体实现

    ACCESS 例子: 复制代码 代码如下: insert into products (ProNumber,CASNumber,Cnname,Price,Enname,Baozhuang,Pinpai) select ProNumber,CASNumber,Cnname,Price,Enname,Baozhuang,Pinpai from product22 1.用一句sql从一个表里面取出数据导入另外一个表里面.这个对不同程序之间的数据转换很有用处,而且速度快,数据完整: insert int

  • Oracle两张表关联批量更新其中一张表的数据

    方法一(推荐): UPDATE 表2 SET 表2.C = (SELECT B FROM 表1 WHERE 表1.A = 表2.A) WHERE EXISTS (SELECT 1 FROM 表1 WHERE 表1.A = 表2.A); 尤其注意最后的外层where条件尤为重要,是锁定其批量更新数据的范围. 方法二: MERGE INTO 表2 USING 表1 ON (表2.A = 表1.A) -- 条件是 A 相同 WHEN MATCHED THEN UPDATE SET 表2.C = 表1.

  • 在Oracle数据库中同时更新两张表的简单方法

    以前只会写一些简单的updaet语句,比如updae table set c1='XXX' 之类的 今天遇到一个数据订正的问题,项目背景如下,有个表A,有两个字段a1,a2还有一个关联表B,其中也有两个字段,b1和b2.其中a2和b2是关联的,想把A中的字段a1更新成B中的b1 理论上sql应该挺好写的,但是在oralce中实现了半天一直报语法错误.而且确实还有些小小细节没有注意到. 首先上测试数据 表1,ZZ_TEST1 表2,ZZ_TEST2 要把表一的text更新成表二的text1值,对应

  • 一条SQL更新语句的执行过程解析

    目录 一.执行过程 二.日志模块 1.物理日志redo log redo log的使用场景 redolog配置 2.逻辑日志binlog 两阶段提交 binlog使用场景 前言: 上一篇文章讲解了SQL查询语句执行的过程,并介绍了执行过程中涉及的处理模块.回顾一下,一条查询语句的执行过程一般是经过连接器.分析器.优化器.执行器等功能模块,最后到达存储引擎. 一.执行过程 在SQL查询语句执行的过程中,我们学习过 SQL 语句基本的执行链路,这里我再把那张图拿过来,你也可以先简单看看这个图回顾下.

  • mysql把一个表某个字段的内容复制到另一张表的某个字段的SQL语句写法

    需求:把一个表某个字段内容复制到另一张表的某个字段. 实现sql语句1: 复制代码 代码如下: UPDATE file_manager_folder f1LEFT OUTER JOIN file_manager_folder f2     ON f1.name = f2.name AND f2.parentId = 54SET f1.parentId = 54 WHERE f2.name IS NULL AND f1.id IN (1,2,3); 实现sql语句2: 复制代码 代码如下: upd

  • sql更新语句中update set from用法实现

    执行一般的sql更新语句为update table_name set column_name=value where column_name1=value1;但是我们有时候需要将某个表用的字段根据两个表中相关字段更新为另一个表中某个字段的数据,即a表中主键aid在b表中有个外键bid相关,b表中字段b需要根据a.b表对应id更新为a表中字段c的数据,如果根据以上的sql一条一条的更新会非常浪费时间,所以我们需要用到update set from的语句用法. 在数据库中有一张表为student,如

  • 数据库中两张表之间的数据同步增加、删除与更新实现思路

    分别创建增加.删除.更新的触发器(Trigger)来达到两张表之间数据同步的目的. 1:数据同步增加: 如有两张表--A表和B表,创建触发器使当A表插入数据后B表也同步插入数据.其中B表插入数据的字段需要同A表中的字段相对应. 复制代码 代码如下: CREATE TRIGGER 触发器名称 ON A表 AFTER INSERT AS BEGIN INSERT INTO B表(B表字段1,B表字段2,B表字段3) SELECT A表字段1,A表字段2,A表字段3 FROM INSERTED END

随机推荐