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


Posted in MySQL onMay 06, 2021

问题场景

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

复现场景

表:主键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更新整张表内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

MySQL 相关文章推荐
Mysql 性能监控及调优
Apr 06 MySQL
MySQL查询学习之基础查询操作
May 08 MySQL
分析MySQL抛出异常的几种常见解决方式
May 18 MySQL
MySQL大小写敏感的注意事项
May 24 MySQL
my.ini优化mysql数据库性能的十个参数(推荐)
May 26 MySQL
MySQL中InnoDB存储引擎的锁的基本使用教程
May 26 MySQL
MySQL 数据恢复的多种方法汇总
Jun 21 MySQL
VS2019连接MySQL数据库的过程及常见问题总结
Nov 27 MySQL
MySQL 开窗函数
Feb 15 MySQL
MySQL中的全表扫描和索引树扫描
May 15 MySQL
Mysql中@和@@符号的详细使用指南
Jun 05 MySQL
浅谈MySql update会锁定哪些范围的数据
Jun 25 MySQL
MySQL创建高性能索引的全步骤
将图片保存到mysql数据库并展示在前端页面的实现代码
MySQL的join buffer原理
Apr 29 #MySQL
Mysql服务添加 iptables防火墙策略的方案
Apr 29 #MySQL
MySQL数据迁移相关总结
MySQL慢查询的坑
解决MySQL存储时间出现不一致的问题
Apr 28 #MySQL
You might like
一个程序下载的管理程序(三)
2006/10/09 PHP
让你同时上传 1000 个文件 (二)
2006/10/09 PHP
php设计模式 Visitor 访问者模式
2011/06/28 PHP
PHP中session变量的销毁
2014/02/27 PHP
php使用百度ping服务代码实例
2014/06/19 PHP
php实现获取农历(阴历)、节日、节气的类与用法示例
2017/11/20 PHP
jQuery+PHP实现图片上传并提交功能
2020/07/27 PHP
jQuery 一个图片切换的插件
2011/10/09 Javascript
Javascript根据指定下标或对象删除数组元素
2012/12/21 Javascript
js/jQuery简单实现选项卡功能
2014/01/02 Javascript
js如何实现淡入淡出效果
2020/11/18 Javascript
微信小程序技巧之show内容展示,上传文件编码问题
2017/01/23 Javascript
jQuery插件FusionCharts绘制的3D饼状图效果实例【附demo源码下载】
2017/03/03 Javascript
微信小程序实现打开内置地图功能【附源码下载】
2017/12/07 Javascript
JavaScript实现的DOM绘制柱状图效果示例
2018/08/08 Javascript
webpack的CSS加载器的使用
2018/09/11 Javascript
小程序实现自定义导航栏适配完美版
2019/04/02 Javascript
[01:45]DOTA2新英雄“神谕者”全方位展示
2014/11/21 DOTA
python使用7z解压软件备份文件脚本分享
2014/02/21 Python
Python的Flask框架中@app.route的用法教程
2015/03/31 Python
Redis使用watch完成秒杀抢购功能的代码
2018/05/07 Python
Python实现根据日期获取当天凌晨时间戳的方法示例
2019/04/09 Python
python实现微信自动回复机器人功能
2019/07/11 Python
在Mac中PyCharm配置python Anaconda环境过程图解
2020/03/11 Python
python将unicode和str互相转化的实现
2020/05/11 Python
Python 忽略文件名编码的方法
2020/08/01 Python
python定义具名元组实例操作
2021/02/28 Python
CSS3 实现飘动的云朵动画
2020/12/01 HTML / CSS
Chicco婴儿用品美国官网:汽车座椅、婴儿推车、高脚椅等
2018/11/05 全球购物
自我鉴定 电子商务专业
2014/01/30 职场文书
社区国庆节活动方案
2014/02/05 职场文书
个人授权委托书样本
2014/09/13 职场文书
上班时间打瞌睡检讨书
2014/09/26 职场文书
2015年妇幼卫生工作总结
2015/05/23 职场文书
中考百日冲刺决心书
2015/09/22 职场文书
golang 定时任务方面time.Sleep和time.Tick的优劣对比分析
2021/05/05 Golang