仅用一句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 Router的安装部署
Apr 24 MySQL
MySQL 如何分析查询性能
May 12 MySQL
Mysql数据库按时间点恢复实战记录
Jun 30 MySQL
MySQL连表查询分组去重的实现示例
Jul 01 MySQL
浅谈MySQL之select优化方案
Aug 07 MySQL
浅谈MySQL函数
Oct 05 MySQL
MySQL中的引号和反引号的区别与用法详解
Oct 24 MySQL
MySQL表类型 存储引擎 的选择
Nov 11 MySQL
分享MySQL常用 内核 Debug 几种常见方法
Mar 17 MySQL
MySQL RC事务隔离的实现
Mar 31 MySQL
mysql sql常用语句大全
Jun 21 MySQL
MySQL创建高性能索引的全步骤
将图片保存到mysql数据库并展示在前端页面的实现代码
MySQL的join buffer原理
Apr 29 #MySQL
Mysql服务添加 iptables防火墙策略的方案
Apr 29 #MySQL
MySQL数据迁移相关总结
MySQL慢查询的坑
解决MySQL存储时间出现不一致的问题
Apr 28 #MySQL
You might like
php下判断数组中是否存在相同的值array_unique
2008/03/25 PHP
解析php根据ip查询所在地区(非常有用,赶集网就用到)
2013/07/01 PHP
PHP打开和关闭文件操作函数总结
2014/11/18 PHP
PHP的Yii框架中Model模型的学习教程
2016/03/29 PHP
PHP 文件锁与进程锁的使用示例
2017/08/07 PHP
[原创]静态页面也可以实现预览 列表不同的显示方式
2006/10/14 Javascript
javascript判断ie浏览器6/7版本加载不同样式表的实现代码
2011/12/26 Javascript
JavaScript打印网页指定区域的例子
2014/05/03 Javascript
全面理解JavaScript中的继承(必看)
2016/06/16 Javascript
js轮盘抽奖实例分析
2020/04/17 Javascript
js自调用匿名函数的三种写法(推荐)
2016/08/19 Javascript
jQuery实现表格元素动态创建功能
2017/01/09 Javascript
angular-ngSanitize模块-$sanitize服务详解
2017/06/13 Javascript
Angular.js实现获取验证码倒计时60秒按钮的简单方法
2017/10/18 Javascript
js定时器实现倒计时效果
2017/11/05 Javascript
js实现简单数字变动效果
2017/11/06 Javascript
js与jQuery实现获取table中的数据并拼成json字符串操作示例
2018/07/12 jQuery
基于AngularJS拖拽插件ngDraggable.js实现拖拽排序功能
2019/04/02 Javascript
详解Vue依赖收集引发的问题
2019/04/22 Javascript
[01:04:30]Fnatic vs Mineski 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/18 DOTA
Python3访问并下载网页内容的方法
2015/07/28 Python
浅谈Python中的私有变量
2018/02/28 Python
python2使用bs4爬取腾讯社招过程解析
2019/08/14 Python
python3 实现函数写文件路径的正确方法
2019/11/27 Python
OpenCV 表盘指针自动读数的示例代码
2020/04/10 Python
解决Keras 自定义层时遇到版本的问题
2020/06/16 Python
python 还原梯度下降算法实现一维线性回归
2020/10/22 Python
纯CSS打造(无图像无js)的非常流行的讲话(语音)气泡效果
2012/12/28 HTML / CSS
美国家具网站:Cymax
2016/09/17 全球购物
幼儿园教师教育感言
2014/02/28 职场文书
乐观自信演讲稿范文
2014/05/21 职场文书
小学“向国旗敬礼”网上签名寄语活动总结
2014/09/27 职场文书
升职自我推荐信范文
2015/03/25 职场文书
cf战队宣传语
2015/07/13 职场文书
react国际化react-intl的使用
2021/05/06 Javascript
MySQL七大JOIN的具体使用
2022/02/28 MySQL