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.按照商品类型和销售地区分组统计商品数量和平均单价,并按平均单价升序显示. -- 按照商品类型和销售地区分组统计商品数量和平均单价,并按平均单价升序 ...
随机推荐
- HTML5中的自定义属性data-*
在html5中,给元素添加自定义属性需要用到data-*,比如data-name,添加完data-自定义属性之后通过元素的dataset属性来访问其值. dataset与getAttribute/se ...
- windows安装程序无法将windows配置为在此计算机上运行
----------------------------------------------- 解决办法: 当出现如上提示的时候,按下shift+f10 会打开命令窗口,进入到C:\windows\s ...
- demo集合
demos的github地址:https://github.com/zy0628/demos 包含以下demo: 1.图片上传.编辑.合成一张图 需求:1.1.拍照或上传本地相册. 2.2.可以截取图 ...
- tornado 作业 自定义模板 UIMethod以UIModule
自定义uimodule s3.py import tornado.ioloop import tornado.web import UIMethod as mt class MainHandler(t ...
- JavaScript:使用递归构建树型菜单
使用递归函数将扁平数据转为树型结构,并渲染到页面 效果图: 代码: <!DOCTYPE html> <html lang="en"> <head> ...
- 四、testNG.xml 简单介绍
TestNG定义了一套非常具体的术语描述测试. testng.xml testng.xml是一个以XML记录所有测试的文件.可以利用这个文件,跑同一个类或者多个不同类里面的测试用例. testng.x ...
- DHCP spooping非法获取地址设置原理
一.DHCP概述 DHCP(动态主机配置协议)是一个局域网的网络协议.指的是由服务器控制一段IP地址范围,客户机登录服务器时就 可以自动获得服务器分配的IP地址和子网掩码.默认情况下,DHCP作为Wi ...
- oranges 笔记第六章
OS 第六次实验随笔 第六章6.1-6.3相关的问题 进程状态保存与恢复 哪些状态 何时保存 保存在哪 如何恢复 特权级变换 用户进程到内核 内核回到用户进程 再次理解TSS .堆栈 从外环进入内环( ...
- 一、Electron + Webpack + Vue 搭建开发环境及打包安装
目录 Webpack + Vue 搭建开发环境及打包安装 ------- 打包渲染进程 Electron + Webpack 搭建开发环境及打包安装 ------- 打包主进程 Electron + ...
- Eureka系列(二) 服务注册Server端具体实现
服务注册 Server端流程 我们先看下面这张图片,这张图片简单描述了下我们EurekaClient 在调用EurekaServer 提供的服务注册Http接口,Server端实现接口执行的大致流 ...