MySQL在按照某个字段分组、排序加序号
事情是这样的,最近领导给了一个新的需求,要求在一张订单表中统计每个人第一次和第二次购买的时间间隔,最后还需要按照间隔统计计数,求出中位数等数据。
- 由于MySQL不想Oracle那般支持行号、中位数等,所以怎么在表中统计处数据成为了关键
订单表结构,主要包含字段如下
- id、订单号、购买人id、下单时间、商品信息字段、购买人信息字段等
1.为了方便后续统计,我的想法是构建了一张中间表,只存储一些关键字段,如购买人id,下单时间,订单号,以及购买的第几次,结构如下图:

字段解释:fans_id:购买人id、order_time:下单时间、tid:订单号、series:商品系列、shop:店铺、times:第几次购买、sync_time:同步时间、effective:是否有效、failure_time:失效时间
2.写了一段代码,处理历史订单,把所有数据按照表中格式添加进去,方便统计,每次新订单进来时,更新一下这个表即可。
3.统计:
-- 统计购买次数最大和最小
select max(times) from 统计表 where effective = '有效'
-- 统计最大购买次数间隔、最小间隔以及平均间隔(中位数的话,由于MySQL没有中位数函数,所以可以利用子查询的SQL通过程序代码计算)
SELECT
max(date) as max,
min(date) as min,
sum( date * mans ) / count( mans ) as avg
FROM
(
SELECT
ifnull(datediff( a.order_time, ( SELECT order_time FROM 统计表 WHERE times = 次数1 AND effective = '有效' AND a.fans_id = fans_id ) ),0) AS date,
a.fans_id,
1 AS mans
FROM
统计表 a
WHERE
a.times = 次数2 AND effective = '有效'
) t
4.由于接收订单后,可能状态会变,无法确保次数准确,更新统计表中每个人的次数SQL如下:
UPDATE
(SELECT @rownum:=@rownum+1 as rn,id,fans_id,order_time from
(SELECT id,fans_id,order_time from
统计表 where fans_id = 购买人 and effective = '有效'
ORDER BY order_time asc) h,
(SELECT @rownum:=0) t) t1,
statistics_repurchase t2
set t2.times=t1.rn where t2.id=t1.id;
5.由于需求还需要支持按照商品系列查询,所以需要在该表基础之上建立临时表以作统计,满足MySQL在按照某个字段分组、排序加序号
第一版SQL如下:
SELECT
a.fans_id,
a.order_time,
a.sync_time,
count( * ) AS times
FROM
统计表 AS a,
统计表 AS b
WHERE
a.fans_id = b.fans_id
AND a.order_time >= b.order_time
AND a.effective = '有效'
AND b.effective = '有效'
AND a.series LIKE concat('%','系列','%')
AND b.series LIKE concat('%','系列','%')
GROUP BY
a.fans_id,
a.id
-- 按照购买人id,按照购买时间进行排序,并标记序号,加上创建表语句如下(建表时需加索引,方便后续查找):
CREATE TABLE 临时表名 (
id INT PRIMARY KEY AUTO_INCREMENT,
fans_id VARCHAR ( 32 ),
order_time datetime,
sync_time date,
times INT ( 6 ),
PRIMARY KEY ( id ),
INDEX mid_fans_id ( fans_id ) USING BTREE,
INDEX mid_order_time ( order_time ) USING BTREE,
INDEX mid_times ( times ) USING BTREE,
INDEX mid_sync_time ( sync_time ) USING BTREE
)
AS
(
SELECT
a.fans_id,
a.order_time,
a.sync_time,
count( * ) AS times
FROM
统计表 AS a,
统计表 AS b
WHERE
a.fans_id = b.fans_id
AND a.order_time >= b.order_time
AND a.effective = '有效'
AND b.effective = '有效'
AND a.series LIKE concat('%','系列','%')
AND b.series LIKE concat('%','系列','%')
GROUP BY
a.fans_id,
a.id
);
-- 由于数据库版本为5.4,所以建完临时表不支持一条sql多次查询,没办法,只能直接创建表
结果如图:

满足了排序,但是后来我发现有一些人是同时间下单的,以至于某些人的times是重复的,于是更新为下面的SQL
SELECT
a.fans_id,
a.order_time,
a.sync_time,
( @i := CASE WHEN @pre_keyword = fans_id THEN @i + 1 ELSE 1 END ) AS times,
@pre_keyword:=fans_id
FROM
( SELECT fans_id, order_time, sync_time FROM 统计表 WHERE effective = '有效' AND series LIKE concat('%','系列','%') ORDER BY fans_id,order_time ) a,
( SELECT @i := 0, @pre_keyword := '' ) AS b
这次的sql是按照时间排序后,判断当前购买人第几次出现,打上序号,由此满足需求
查询结果和上图相同,就不附图了哈
效率这,购买人id,下单时间需要创建索引,否则可能有些慢,测试库中数据大概七百万左右,总体查询可在四秒内完成
希望这篇文章能在开发中给予您一定的帮助,新人博客主,码龄一年,如有更好的方案,望指教!
MySQL在按照某个字段分组、排序加序号的更多相关文章
- mysql分组排序加序号(不用存储过程,就简简单单sql语句哦)
做前端好长时间了,好久没动sql了.在追一个喜欢的女孩,做测试的,有这么个需求求助与本屌丝,机会难得,开始折腾起来,配置mysql,建库,建表.... 一 建表 CREATE TABLE `my_te ...
- mysql分组排序加序号
参照https://www.cnblogs.com/CharlieLau/p/6737243.html 一.需求 新加一个Sort 字段,初始值为1,按照parentID分组添加sort值. 根据原数 ...
- mysql按某一字段分组取最大(小)值所在行的数据
mysql按某一字段分组取最大(小)值所在行的数据 mysql技巧--按某一字段分组取最大(小)值所在行的数据,这是mysql数据库程序员经常用到的在处理一些报表数据时候可以活用!那么猎微网将总结 ...
- MySQL使用用户变量更新分组排序
第一个需求是根据A字段进行排序,排序结果更新到B字段 简单搜索之后,很快得到答案 http://dev.mysql.com/doc/refman/5.7/en/update.html ; ) ORDE ...
- MySQL进阶5--分组函数 / 分组排序和分组查询 group by(having) /order by
MySQL进阶--分组排序和分组查询 group by(having) /order by /* 介绍分组函数 功能:用做统计使用,又称为聚合函数或组函数 1.分类: sum, avg 求和 /平均数 ...
- sql多字段分组排序显示全部数据
建表sql CREATE TABLE `tbl_demo` ( `id` ) COLLATE utf8_bin NOT NULL, `payer_name` ) COLLATE utf8_bin DE ...
- Linux sort 多字段分组排序
常用参数: -t: 指定分隔符 -k: 指定域 -u: 去除重复行 -n: 以数值排序 -r: 降序排序 (sort默认的排序方式是升序) -o: 结果重定向输出到文件 1.源文件: # cat hh ...
- mysql语句求按字段分组后组数是多少
select count(distinct ID) from table Thinkphp CURD写 $count = $model->where($where)->count('dis ...
- 【MySQL作业】多字段分组和 having 子句——美和易思分组查询应用习题
点击打开所使用到的数据库>>> 1.按照商品类型和销售地区分组统计商品数量和平均单价,并按平均单价升序显示. -- 按照商品类型和销售地区分组统计商品数量和平均单价,并按平均单价升序 ...
随机推荐
- js- 对象的连续调用
var jack = { somke : function (){ console.log('I was in the somkeing...cool..'); return this; }, dri ...
- x++ 和 ++x的区别
很多编程语言都会有x++和++x的问题,两个到底是怎么回事? 一个先执行一个后执行的区别 var x = 0; console.log(x++);//0 遇到x++当前执行值不变 console.lo ...
- 关于微信NFC功能开发的链接总结
特此申明:若有侵权,请联系我,我会第一时间删除 一. 小程序开发一般流程: 首先调用 wx.getHCEState(OBJECT), 判断设备是否支持NFC,(ios,android兼容性处理) 调用 ...
- SpringBoot集成Swagger2并配置多个包路径扫描
1. 简介 随着现在主流的前后端分离模式开发越来越成熟,接口文档的编写和规范是一件非常重要的事.简单的项目来说,对应的controller在一个包路径下,因此在Swagger配置参数时只需要配置一 ...
- 自顶向下redis4.0(3)命令与dict
redis4.0的命令 简介 目录 redis4.0的命令 简介 正文 redisCommand与redisCommandTable 初始化命令 执行命令 set指令与字典 参考文献 正文 redis ...
- Django DRF 分页
Django DRF 分页 分页在DRF当中可以一共有三种,可以通过setttings设置,也可也通过自定义设置 PageNumberPagination 使用URL http://127.0.0.1 ...
- 重写Laravel异常处理类
现在开发前后端分离变得越来越流行了,后端只提供接口返回json格式的数据,即使是错误信息也要以json格式来返回,然而目前无论是Laravel框架还是ThinkPHP框架,都只提供了返回json数据的 ...
- 多任务-python实现-继承Thread类,单独编写一个类(2.1.2)
@ 目录 1.thread类 1.thread类 threding代码实现 import threading import time class MyThread(threading.Thread): ...
- 程序猿的浪漫:用python画动态爱心
初级画心 学Python,感觉你们的都好复杂,那我来个简单的,我是直接把心形看作是一个正方形+两个半圆:
- APP端有原生态的控件,但嵌入了H5页面,怎么定位到H5页面的元素
appium 通常有很多种定位元素方法,例如xpath,driver.find_element_by_accessibility_id等,安卓sdk自带的uiautomatorviewer但是对于H5 ...