MySQL购买间隔时间计算

因为一些原因被要求按照客户消费金额分类披露客户购买间隔时间,并对其合理性进行补充分析。网上查出来的方法都是你抄我的我抄你的,于是乎自己开始思考如何去实现。

数据准备

#MySQL80018

CREATE TABLE `order_info`  (
  `id` bigint(20) NOT NULL,
  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户名',
  `pay_time` datetime(0) NULL DEFAULT NULL COMMENT '付款时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '订单信息' ROW_FORMAT = Dynamic;

INSERT INTO `order_info` VALUES (1, '张三', '2020-01-01 12:50:01');
INSERT INTO `order_info` VALUES (2, '李四', '2020-01-02 12:46:38');
INSERT INTO `order_info` VALUES (3, '李四', '2020-01-04 08:23:06');
INSERT INTO `order_info` VALUES (4, '王五', '2020-02-06 09:47:42');
INSERT INTO `order_info` VALUES (5, '王五', '2020-02-07 18:42:23');
INSERT INTO `order_info` VALUES (6, '王五', '2020-03-12 20:22:45');
INSERT INTO `order_info` VALUES (7, '赵六', '2020-08-01 10:36:49');
INSERT INTO `order_info` VALUES (8, '赵六', '2020-08-04 12:37:09');
INSERT INTO `order_info` VALUES (9, '赵六', '2020-08-14 06:20:33');
INSERT INTO `order_info` VALUES (10, '赵六', '2020-08-27 10:38:02');

实现思路

可能不是最优思路,以下是我的实现方法。订单间隔时间只比较同一用户的订单。

将原来的表需要的字段查出,添加行号字段,按照名字和时间升序排序,当作临时表用。

SELECT
	@r := @r + 1 AS 'r',
	`name`,
	pay_time
FROM
	order_info,
	( SELECT @r := 0 ) t
ORDER BY
	`name`,
	pay_time
rnamepay_time
1张三2020-01-01 12:50:01
2李四2020-01-02 12:46:38
3李四2020-01-04 08:23:06
4王五2020-02-06 09:47:42
5王五2020-02-07 18:42:23
6王五2020-03-12 20:22:45
7赵六2020-08-01 10:36:49
8赵六2020-08-04 12:37:09
9赵六2020-08-14 06:20:33
10赵六2020-08-27 10:38:02

将上面的临时表左连接自己(@r要换名字,不然无法查出后面的数据),连接条件为名字相同,序号错位一格。只有用户有两单以上的时候,才会出现后面的数据。

SELECT
	*
FROM
	(
	SELECT
		@r := @r + 1 AS 'r',
		`name`,
		pay_time
	FROM
		order_info,
		( SELECT @r := 0 ) t
	ORDER BY
		`name`,
		pay_time
	) temp
	LEFT JOIN (
	SELECT
		@rownum := @rownum + 1 AS 'r',
		`name`,
		pay_time
	FROM
		order_info,
		( SELECT @rownum := 0 ) t
	ORDER BY
		`name`,
		pay_time
	) temp2 ON temp.r = temp2.r + 1
	AND temp.`name` = temp2.`name`
rnamepay_timer(1)name(1)pay_time(1)
1张三2020-01-01 12:50:01
2李四2020-01-02 12:46:38
3李四2020-01-04 08:23:062李四2020-01-02 12:46:38
4王五2020-02-06 09:47:42
5王五2020-02-07 18:42:234王五2020-02-06 09:47:42
6王五2020-03-12 20:22:455王五2020-02-07 18:42:23
7赵六2020-08-01 10:36:49
8赵六2020-08-04 12:37:097赵六2020-08-01 10:36:49
9赵六2020-08-14 06:20:338赵六2020-08-04 12:37:09
10赵六2020-08-27 10:38:029赵六2020-08-14 06:20:33

过滤掉空数据,使用TIMESTAMPDIFF函数计算时间间隔

TIMESTAMPDIFF(unit,begin,end);
unit可以是MICROSECOND,SECOND,MINUTE,HOUR,DAY,WEEK,MONTH,QUARTER,YEAR
beginend是DATE或DATETIME表达式

SELECT
	temp.`name`,
	temp.pay_time AS afterTime,
	temp2.pay_time AS beforeTime,
	TIMESTAMPDIFF( DAY, temp2.pay_time, temp.pay_time ) AS diff
FROM
	(
	SELECT
		@r := @r + 1 AS 'r',
		`name`,
		pay_time
	FROM
		order_info,
		( SELECT @r := 0 ) t
	ORDER BY
		`name`,
		pay_time
	) temp
	LEFT JOIN (
	SELECT
		@rownum := @rownum + 1 AS 'r',
		`name`,
		pay_time
	FROM
		order_info,
		( SELECT @rownum := 0 ) t
	ORDER BY
		`name`,
		pay_time
	) temp2 ON temp.r = temp2.r + 1
	AND temp.`name` = temp2.`name`
WHERE
	temp2.pay_time IS NOT NULL
nameafterTimebeforeTimediff
李四2020-01-04 08:23:062020-01-02 12:46:381
王五2020-02-07 18:42:232020-02-06 09:47:421
王五2020-03-12 20:22:452020-02-07 18:42:2334
赵六2020-08-04 12:37:092020-08-01 10:36:493
赵六2020-08-14 06:20:332020-08-04 12:37:099
赵六2020-08-27 10:38:022020-08-14 06:20:3313

优化(2021/11/10)

  1. LEFT JOIN可以使用INNER JOIN替代,这样就不用加WHERE条件WHERE temp2.pay_time IS NOT NULL去除空白数据了。

  2. 序号可以使用窗口函数row_number() over()来替代。
    最终sql如下:

SELECT
	temp.`name`,
	temp.pay_time AS afterTime,
	temp2.pay_time AS beforeTime,
	TIMESTAMPDIFF( DAY, temp2.pay_time, temp.pay_time ) AS diff
FROM
	(
	SELECT
		row_number() over(partition by name order by pay_time) AS r,
		`name`,
		pay_time
	FROM
		order_info
	ORDER BY
		`name`,
		pay_time
	) temp
	INNER JOIN (
	SELECT
		row_number() over(partition by name order by pay_time) AS r,
		`name`,
		pay_time
	FROM
		order_info
	ORDER BY
		`name`,
		pay_time
	) temp2 ON temp.r = temp2.r + 1
	AND temp.`name` = temp2.`name`

最早发布于 2020/08/27
版权声明:本文为xuchl的原创文章,修改或转载请附上原文出处链接或CSDN链接
原文链接:原文链接:https://xuchunlei.top/2020/08/27/MySQL购买间隔时间计算/

微信公众号链接

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值