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 相关文章推荐
多表查询、事务、DCL
Apr 05 MySQL
Navicat for MySQL的使用教程详解
May 27 MySQL
浅谈MySQL 亿级数据分页的优化
Jun 15 MySQL
详解MySQL多版本并发控制机制(MVCC)源码
Jun 23 MySQL
MySQL系列之十五 MySQL常用配置和性能压力测试
Jul 02 MySQL
一条慢SQL语句引发的改造之路
Mar 16 MySQL
数据分析数据库ClickHouse在大数据领域应用实践
Apr 03 MySQL
mysql使用 not int 子查询隐含陷阱
Apr 12 MySQL
MySQL视图概念以及相关应用
Apr 19 MySQL
mysql 子查询的使用
Apr 28 MySQL
mysql查看表结构的三种方法总结
Jul 07 MySQL
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
PHP HTML代码串 截取实现代码
2009/06/29 PHP
php通过asort()给关联数组按照值排序的方法
2015/03/18 PHP
php使用gzip压缩传输js和css文件的方法
2015/07/29 PHP
laravel 查询数据库获取结果实现判断是否为空
2019/10/24 PHP
JavaScript获取GridView选择的行内容
2009/04/14 Javascript
jQuery Tools tab(幻灯片)
2012/07/14 Javascript
基于JQuery的类似新浪微博展示信息效果的代码
2012/07/23 Javascript
jQuery DOM操作实例
2014/03/05 Javascript
jquery插件开发之实现google+圈子选择功能
2014/03/10 Javascript
PHPMyAdmin导入时提示文件大小超出PHP限制的解决方法
2015/03/30 Javascript
深入理解Node.js中通用基础设计模式
2017/09/19 Javascript
手写Node静态资源服务器的实现方法
2018/03/20 Javascript
浅析Vue实例以及生命周期
2018/08/14 Javascript
浅谈webpack devtool里的7种SourceMap模式
2019/01/14 Javascript
微信小程序实现左右列表联动
2020/05/19 Javascript
详解VScode编辑器vue环境搭建所遇问题解决方案
2019/04/26 Javascript
js实现轮播图效果 纯js实现图片自动切换
2020/08/09 Javascript
Django框架 querySet功能解析
2019/09/04 Python
Python调用scp向服务器上传文件示例
2019/12/22 Python
简单了解python关键字global nonlocal区别
2020/09/21 Python
利用python为PostgreSQL的表自动添加分区
2021/01/18 Python
学校门卫工作职责
2013/12/07 职场文书
教师自我反思材料
2014/02/14 职场文书
搞笑爱情保证书
2014/04/29 职场文书
幼儿教师师德演讲稿
2014/05/06 职场文书
心理咨询专业自荐信
2014/07/07 职场文书
党员贯彻十八大精神思想汇报范文
2014/10/25 职场文书
布达拉宫导游词
2015/02/02 职场文书
简爱电影观后感
2015/06/10 职场文书
新教师教学工作总结
2015/08/14 职场文书
2016党员干部政治学习心得体会
2016/01/23 职场文书
读鲁迅先生的经典名言
2019/08/20 职场文书
您对思维方式了解多少?
2019/12/09 职场文书
JavaScript分页组件使用方法详解
2021/07/26 Javascript
vue实现可以快进后退的跑马灯组件
2022/04/08 Vue.js
python小型的音频操作库mp3Play
2022/04/24 Python