mysql 获取相邻数据项


Posted in MySQL onMay 11, 2022

通过当前排序字段获取相邻数据项

1.业务场景

(1)需要专门以一个弹窗页面展示一项数据的所有字段值.其中一些字段值长度较大。

(2)能够左右切换上一项下一项数据

(3)存在可排序的字段,如以id进行排序

2.思路

2.1 sql

1>查询前一项,查询小于当前id的项逆序取第一个

2>查询后一项,查询大于当前id的项正序取第一个

3>连接两项结果

2.2 页面逻辑

(1)在展示当前项时获取好两相邻的数据,在做切换时直接填充数据

(2)切换数据展示时同样再次获取当前项两相邻数据

以此(1)(2)往复

3.sql

例:查询id为40两相邻的数据

( SELECT * FROM [表名] WHERE id < 40 ORDER BY id DESC LIMIT 1 ) UNION
(
    SELECT
        * 
    FROM
        [表名]
    WHERE
        id > 40 
    ORDER BY
        id 
    LIMIT 1
)

同表相邻数据查询或计算

用户下相邻订单的时间差举例

这里主要介绍一下,在一张数据表下对相邻的数据进行一个相关查询和计算;

拿一个在电商中最常见的情况,计算一下用户首单和第二单的时间间隔这样的数据来举例,如下:

id customer_id created_at
1 1 2017-07-21 09:43:02
2 12 2017-07-25 11:37:48
3 10 2017-07-25 11:43:41
4 1 2017-07-27 01:27:22
5 10 2017-07-27 07:46:45
6 1 2017-07-27 10:21:37
7 12 2017-07-27 13:26:19

查询用户首单和第二单的时间间隔:

SELECT
	m.customer_id,
	sfo.created_at as '首单时间',
	m.created_at as '第二单时间',
	(unix_timestamp(m.created_at) - unix_timestamp(sfo.created_at))/86400 as '两单相差天数'
	
FROM
	sales_flat_order m 
LEFT JOIN 
	sales_flat_order sfo on m.customer_id = sfo.customer_id and sfo.created_at < m.created_at
WHERE
	(
		SELECT
			count(*)
		FROM
			sales_flat_order n
		WHERE
			m.customer_id = n.customer_id
			AND m.created_at > n.created_at
	) = 1
GROUP BY m.customer_id

查询结果是:

customer_id 首单时间 第二单时间 两单时间差
1 2017-07-21 09:43:02 2017-07-27 01:27:22 5.6558
12 2017-07-25 11:37:48 2017-07-27 13:26:19 2.0754
10 2017-07-25 11:43:41 2017-07-27 07:46:45 1.8355

整个原理如下:

  • 将一张表查询两次得到两组数据,分别为别名m和别名n的两组数据;
  • 以m为主,用n的数据和m的数据作对比,通过created_at的判断过滤掉一些无用数据;
  • 使用count()函数统计满足条件的数据个数;
  • 统计数为1时说明n表中比m表中时间小的只有1条,m中的该条数据也就是该用户下的第二笔订单;
  • 通过LEFT JOIN联表,通过created_at找到比第二单更早的一单也就是用户的首单;
  • 利用unix_timestamp把得到的两条数据的created_at做差,得到了两笔订单的时间间隔;

下面做了一下拓展,可以查询任意相连的两笔订单的时间间隔:

SELECT
	m.customer_id,
	m.created_at as '后一单时间',
	SUBSTRING_INDEX(
		GROUP_CONCAT(sfo.created_at ORDER BY sfo.created_at DESC),
		',',
		1
	) as '前一单时间',
	(unix_timestamp(m.created_at) - unix_timestamp(
		SUBSTRING_INDEX(
			GROUP_CONCAT(sfo.created_at ORDER BY sfo.created_at DESC),
			',',
			1
		)
	))/86400 as '两单相差天数'
FROM
	sales_flat_order m 
LEFT JOIN 
	sales_flat_order sfo on m.customer_id = sfo.customer_id and sfo.created_at < m.created_at
WHERE
	(
		SELECT
			count(*)
		FROM
			sales_flat_order n
		WHERE
			m.customer_id = n.customer_id
			AND m.created_at > n.created_at
	) = 2
GROUP BY m.customer_id;

得到数据如下:

customer_id 后一单时间 前一单时间 两单时间差
1 2017-07-27 10:21:37 2017-07-27 01:27:22 0.3710

这里判断的是统计数为2的,也就是用户的第二单和第三单的时间间隔计算,因为用户10和12只有两单所以结果中无这两个用户;

整个原理如下:

  • 将一张表查询两次得到两组数据,分别为别名m和别名n的两组数据;
  • 以m为主,用n的数据和m的数据作对比,通过created_at的判断过滤掉一些无用数据;
  • 使用count()函数统计满足条件的数据个数;
  • 筛选之后m中得到的是第三笔订单;
  • 通过LEFT JOIN联表,通过created_at找到比第三笔订单时间早的订单,这里会从sfo中得到两笔订单;
  • 利用GROUP_CONCAT函数每组订单中各得到的两笔订单利用created_at进行降序排序,然后得到通过‘,’连接的两条数据的时间,如下:2017-07-27 01:27:22,2017-07-21 09:43:02
  • 使用SUBSTRING_INDEX函数通过’,'将数据拆分再拿到第一条数据,也就是第二笔订单的时间了;
  • 利用unix_timestamp对created_at作差,得到两笔订单的时间间隔;

这只是我想到的应对这种场景通过SQL语句进行查询的方法。 

MySQL 相关文章推荐
MySQL安装后默认自带数据库的作用详解
Apr 27 MySQL
详解MySQL中的主键与事务
May 27 MySQL
MySQL连接查询你真的学会了吗?
Jun 02 MySQL
MySQL中in和exists区别详解
Jun 03 MySQL
MySQL 全文检索的使用示例
Jun 07 MySQL
解决mysql模糊查询索引失效问题的几种方法
Jun 18 MySQL
MySQL的安装与配置详细教程
Jun 26 MySQL
MySQL系列之十四 MySQL的高可用实现
Jul 02 MySQL
排查MySQL生产环境索引没有效果
Apr 11 MySQL
单机多实例部署 MySQL8.0.20
May 15 MySQL
一文解答什么是MySQL的回表
Aug 05 MySQL
数据设计之权限的实现
Aug 05 MySQL
MySQL脏读,幻读和不可重复读
May 11 #MySQL
MySql数据库 查询时间序列间隔
May 11 #MySQL
Mysql中常用的join连接方式
May 11 #MySQL
MySQL的prepare使用以及遇到的bug
May 11 #MySQL
MySQL批量更新不同表中的数据
May 11 #MySQL
mysql查找连续出现n次以上的数字
May 11 #MySQL
mysql如何查询连续记录
May 11 #MySQL
You might like
真正根据utf8编码的规律来进行截取字符串的函数(utf8版sub_str )
2012/10/24 PHP
php调用MySQL存储过程的方法集合(推荐)
2013/07/03 PHP
php实现cc攻击防御和防止快速刷新页面示例
2014/02/13 PHP
PHP数组排序之sort、asort与ksort用法实例
2014/09/08 PHP
php实现根据字符串生成对应数组的方法
2014/09/22 PHP
php使用cookie保存登录用户名的方法
2015/01/26 PHP
php去除字符串中空字符的常用方法小结
2015/03/17 PHP
PHP数据源架构模式之表入口模式实例分析
2020/01/23 PHP
PHP8.0新功能之Match表达式的使用
2020/07/19 PHP
基于thinkphp5框架实现微信小程序支付 退款 订单查询 退款查询操作
2020/08/17 PHP
jQuery 打造动态下滑菜单实现说明
2010/04/15 Javascript
关于js中for in的缺陷浅析
2013/12/02 Javascript
js实现prototype扩展的方法(字符串,日期,数组扩展)
2016/01/14 Javascript
基于RequireJS和JQuery的模块化编程——常见问题全面解析
2016/04/14 Javascript
浅析在javascript中创建对象的各种模式
2016/05/06 Javascript
JS实现的多张图片轮流播放幻灯片效果
2016/07/22 Javascript
jQuery遍历节点树方法分析
2016/09/08 Javascript
Node.js使用MySQL连接池的方法实例
2018/02/11 Javascript
微信小程序动态添加view组件的实例代码
2019/05/23 Javascript
解决vue的过渡动画无法正常实现问题
2019/10/31 Javascript
JS实现简单省市二级联动
2019/11/27 Javascript
JS实现压缩上传图片base64长度功能
2019/12/03 Javascript
实例讲解Python编程中@property装饰器的用法
2016/06/20 Python
Python编程之string相关操作实例详解
2017/07/22 Python
python实现excel读写数据
2021/03/02 Python
python plotly绘制直方图实例详解
2019/07/22 Python
通过CSS3的object-fit来调整图片适配尺寸的技巧简介
2016/02/27 HTML / CSS
de Bijenkorf比利时官网:荷兰最知名的百货商店
2017/06/29 全球购物
Origins悦木之源英国官网:雅诗兰黛集团高端植物护肤品牌
2017/11/06 全球购物
英国日常交易网站:Wowcher
2018/09/04 全球购物
JAVA和C++区别都有哪些
2015/03/30 面试题
小加工厂管理制度
2014/01/21 职场文书
2014年小学生教师节演讲稿范文
2014/09/10 职场文书
领导班子作风建设剖析材料
2014/10/11 职场文书
2015年质量月活动总结报告
2015/03/27 职场文书
postgreSQL数据库基础知识介绍
2022/04/12 PostgreSQL