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 05 MySQL
mysql优化
Apr 06 MySQL
MySQL主从复制断开的常用修复方法
Apr 07 MySQL
52条SQL语句教你性能优化
May 25 MySQL
MySQL如何使用使用Xtrabackup进行备份和恢复
Jun 21 MySQL
mysql连接查询中and与where的区别浅析
Jul 01 MySQL
SQL之各种join小结详细讲解
Aug 04 MySQL
mysql配置SSL证书登录的实现
Sep 04 MySQL
Mysql binlog日志文件过大的解决
Oct 05 MySQL
排查并解决MySQL生产库内存使用率高的报警
Apr 11 MySQL
mysql 索引的数据结构为什么要采用B+树
Apr 26 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
dedecms 制作模板中使用的全局标记图文教程
2007/03/11 PHP
PHP生成条形码大揭秘
2015/09/24 PHP
PHP实现的Redis多库选择功能单例类
2017/07/27 PHP
PHP仿tp实现mvc框架基本设计思路与实现方法分析
2018/05/23 PHP
php empty 函数判断结果为空但实际值却为非空的原因解析
2018/05/28 PHP
javascript第一课
2007/02/27 Javascript
利用js获取服务器时间的两个简单方法
2010/01/08 Javascript
JS+CSS 制作的超级简单的下拉菜单附图
2013/11/22 Javascript
用html5 js实现点击一个按钮达到浏览器全屏效果
2014/05/28 Javascript
javascript实现playfair和hill密码算法
2014/12/07 Javascript
jQuery实现表单提交时判断的方法
2014/12/13 Javascript
Java Mybatis框架入门基础教程
2015/09/21 Javascript
Javascript中apply、call、bind的巧妙使用
2016/08/18 Javascript
简单谈谈关于Angular Cli打包的事
2017/09/05 Javascript
JS+canvas动态绘制饼图的方法示例
2017/09/12 Javascript
基于vue2实现上拉加载功能
2017/11/28 Javascript
jquery实现掷骰子小游戏
2019/10/24 jQuery
vue计算属性+vue中class与style绑定(推荐)
2020/03/30 Javascript
vue实现标签云效果的示例
2020/11/09 Javascript
python k-近邻算法实例分享
2014/06/11 Python
Python中encode()方法的使用简介
2015/05/18 Python
Python编程中对super函数的正确理解和用法解析
2016/07/02 Python
Python之dict(或对象)与json之间的互相转化实例
2018/06/05 Python
pycharm的console输入实现换行的方法
2019/01/16 Python
几行Python代码爬取3000+上市公司的信息
2019/01/24 Python
Python 元组拆包示例(Tuple Unpacking)
2019/12/24 Python
浅谈python量化 双均线策略(金叉死叉)
2020/06/03 Python
Python计算矩阵的和积的实例详解
2020/09/10 Python
Python WebSocket长连接心跳与短连接的示例
2020/11/24 Python
使用html5新特性轻松监听任何App自带返回键的示例
2018/03/13 HTML / CSS
PUMA澳大利亚官方网站:德国运动品牌
2018/10/19 全球购物
日本AOKI官方商城:AOKI西装
2020/06/11 全球购物
社区四风存在问题及整改措施
2014/10/26 职场文书
2015年乡镇安全生产工作总结
2015/05/19 职场文书
有关浪费资源的建议书
2015/09/14 职场文书
SQL试题 使用窗口函数选出连续3天登录的用户
2022/04/24 Oracle