linux mysql dengl_mysql中类似oracle的over分组实现
今天,看到别人问问题,需求大概是这样的。
id
s
开始时间
结束时间
1
20
2001-01-01 08:10:20
2001-01-01 08:10:40
1
9
2001-01-01 08:10:41
2001-01-01 08:10:50
1
60
2001-01-01 08:10:51
2001-01-01 08:11:51
1
2
2001-01-01 08:12:51
2001-01-01 08:12:53
2
51
2001-01-01 08:10:00
2001-01-01 08:10:51
2
60
2001-01-01 08:11:00
2001-01-01 08:12:00
2
5
2001-01-01 08:13:00
2001-01-01 08:13:05
2
15
2001-01-01 08:13:06
2001-01-01 08:13:21
2
5
2001-01-01 08:13:25
2001-01-01 08:13:30 要统计用户相同,时间连续(也就是结束时间和下一次的开始时间相差1秒)的结果,最终呈现
id,总的时间间隔,这个时间段的开始时间,这个时间段的结束时间。
如上面id=1,出来结果应该是1,
1
89
2001-01-01 08:10:20
2001-01-01 08:11:51
1
2
2001-01-01 08:12:51
2001-01-01 08:12:53 =============================================================================
对于上面这个需求,如果用oracle,那么应该比较好实现。用group by,over,lag的方式很轻松就能搞定。但对于mysql,似乎统计函数比较少。
本来对于MySQL复杂的SQL应用也不算熟悉。于是试着写了写。
一、我自己整理了一下思路,第一步目标:
1、需要整理出一个唯一字段分组
2、需要在下一条记录显示上一条记录的结束时间
二、根据第一步整理的目标
1、对第一个小目标分解
1)首先每行的唯一行号,这是形成唯一字段分组可以借用的。
2)标记位要能够区分不同用户,比如上一个用户的结束时间和下一个用户的开始时间刚好连了起来,要能区分出是两个用户。
2、第二个小目标分解
1)把时间转化为数字或者字符,去掉不必要字符,这样便于后续处理
三、创建测试
1、添加表
create table time_log(
id int, --用户id
s int, --时间间隔
start_t varchar(20), --开始时间
end_t varchar(20) --结束时间
)2、添加测试数据
insert into time_log(id,s,start_t,end_t)
values(1,20,'2001-01-01 08:10:20','2001-01-01 08:10:40');
insert into time_log(id,s,start_t,end_t)
values(1,9,'2001-01-01 08:10:41','2001-01-01 08:10:50');
insert into time_log(id,s,start_t,end_t)
values(1,60,'2001-01-01 08:10:51','2001-01-01 08:11:51');
insert into time_log(id,s,start_t,end_t)
values(1,2,'2001-01-01 08:12:51','2001-01-01 08:12:53');
insert into time_log(id,s,start_t,end_t)
values(2,51,'2001-01-01 08:10:00','2001-01-01 08:10:51');
insert into time_log(id,s,start_t,end_t)
values(2,60,'2001-01-01 08:11:00','2001-01-01 08:12:00');
insert into time_log(id,s,start_t,end_t)
values(2,5,'2001-01-01 08:13:00','2001-01-01 08:13:05');
insert into time_log(id,s,start_t,end_t)
values(2,15,'2001-01-01 08:13:06','2001-01-01 08:13:21');
insert into time_log(id,s,start_t,end_t)
values(2,5,'2001-01-01 08:13:25','2001-01-01 08:13:30');
3、SQL
1)根据第一步目标
出来SQL
select @rownum:=@rownum+1 as rownum,@preEndTime as preendnum,@preEndTime:=dendnum ,t.* from
(
select t.*
,CONCAT(id,'-',date_format(str_to_date(t.START_T,'%Y-%m-%d %h:%i:%s'),'%Y%m%d%h%i%s'))as dstartnum
,CONCAT(id,'-',date_format(str_to_date(t.end_T,'%Y-%m-%d %h:%i:%s'),'%Y%m%d%h%i%s')+1) as dendnum
,date_format(str_to_date(t.START_T,'%Y-%m-%d %h:%i:%s'),'%Y%m%d%h%i%s') istart
,date_format(str_to_date(t.end_T,'%Y-%m-%d %h:%i:%s'),'%Y%m%d%h%i%s') iend
from time_log t
) t,(SELECT @preEndTime:='',@rownum:=0) r
1)根据出来的列整理,生成id,标记连续
select t.*,case when preendnum=dstartnum then 0 else rownum end as di
from
(
select @rownum:=@rownum+1 as rownum,@preEndTime as preendnum,@preEndTime:=dendnum ,t.* from
(
select t.*
,CONCAT(id,'-',date_format(str_to_date(t.START_T,'%Y-%m-%d %h:%i:%s'),'%Y%m%d%h%i%s'))as dstartnum
,CONCAT(id,'-',date_format(str_to_date(t.end_T,'%Y-%m-%d %h:%i:%s'),'%Y%m%d%h%i%s')+1) as dendnum
,date_format(str_to_date(t.START_T,'%Y-%m-%d %h:%i:%s'),'%Y%m%d%h%i%s') istart
,date_format(str_to_date(t.end_T,'%Y-%m-%d %h:%i:%s'),'%Y%m%d%h%i%s') iend
from time_log t
) t,(SELECT @preEndTime:='',@rownum:=0) r
) t
2)最终一步步处理,出来最终SQL
select id,s_nums 时间s
,str_to_date(istarttimes,'%Y-%m-%d %h:%i:%s') as 开始时间
,end_t as 结束时间 from
(
select case when @knum=dirow then 0 else dirow end as flag,@knum:=dirow,t.* from
(
select * from (
select t.*,date_sub(end_t, interval totals day_second) as istarttimes from
(
select t.*,@rowid:=@rowid+di as dirow,@sums:=case when di=0 then @sums+s+1 else s end as totals
,@sums2:=case when di=0 then @sums2+s+0 else s end as s_nums from
(
select t.*,case when preendnum=dstartnum then 0 else rownum end as di
from
(
select @rownum:=@rownum+1 as rownum,@preEndTime as preendnum,@preEndTime:=dendnum ,t.* from
(
select t.*
,CONCAT(id,'-',date_format(str_to_date(t.START_T,'%Y-%m-%d %h:%i:%s'),'%Y%m%d%h%i%s'))as dstartnum
,CONCAT(id,'-',date_format(str_to_date(t.end_T,'%Y-%m-%d %h:%i:%s'),'%Y%m%d%h%i%s')+1) as dendnum
,date_format(str_to_date(t.START_T,'%Y-%m-%d %h:%i:%s'),'%Y%m%d%h%i%s') istart
,date_format(str_to_date(t.end_T,'%Y-%m-%d %h:%i:%s'),'%Y%m%d%h%i%s') iend
from time_log t
) t,(SELECT @preEndTime:='',@rownum:=0) r
) t
) t,(SELECT @rowid:=0) r
) t
) t order by rownum desc
) t,(SELECT @knum:=-1) r
) t where t.flag<> 0 order by rownum sql没有大量注释,但一层层剥离,应该很容易理解,这也没有优化。如果在项目开发中让我选择,我肯定用存储过程。
linux mysql dengl_mysql中类似oracle的over分组实现相关推荐
- mysql 类似 nvl,浅谈mysql可有类似oracle的nvl的函数
浅谈mysql可有类似oracle的nvl的函数 要用ifnull,而不是isnull isnull是判断是否为null,返回值是1表示null或者0表示不为空 ifnull等同于oracle的nvl ...
- MySQL中类似ORACLE中decode()判断语句实现
一. IF函数 1. IF语句 IF expression THEN statements; END IF; 2. IF ELSE语句 IF expression THENstatements; EL ...
- linux mysql配置文件中修改ip_linux下mysql配置文件my.cnf详解
basedir = path 使用给定目录作为根目录(安装目录). character-sets-dir = path 给出存放着字符集的目录. datadir = path 从给定目录读取数据库文件 ...
- 在红帽中安装oracle,在红帽企业Linux 5.4中安装Oracle Database 10g
按照Quick Installation Guide 10g Release 2 (10.2) for Linux x86文档安装即可. 安装过程中碰到的问题: 准备从以下地址启动 Oracle Un ...
- linux mysql 客户端工具下载,Oracle客户端工具之Oracle SQL Handler for Linux
Oracle SQL Handler, 是专为Oracle数据库开发人员及操作人员精心打造的一款Oracle开发工具(客户端工具).国产原创,精品奉献,其优点特点如下: (1)跨平台, 能运行于平台 ...
- linux mysql timestamp_MYSQL中TIMESTAMP类型的使用
MYSQL中TIMESTAMP类型的默认值 MYSQL中TIMESTAMP类型可以设定默认值,就像其他类型一样. 1.自动UPDATE 和INSERT 到当前的时间: 表: ------------- ...
- linux mysql revoke_mysql中授权(grant)和撤销授权(revoke)等命令的用法详解
MySQL的权限系统围绕着两个概念: 认证->确定用户是否允许连接数据库服务器 授权->确定用户是否拥有足够的权限执行查询请求等. 如果认证不成功的话,哪么授权肯定是无法进行的. revo ...
- mysql 类似 oracle connect by,mysql中实现相仿oracle的SYS_CONNECT_BY_PATH功能
mysql中实现类似oracle的SYS_CONNECT_BY_PATH功能 oracle中的SYS_CONNECT_BY_PATH函数为开发带来了便利,mysql中如何实现类的功能呢? DELIMI ...
- 【mysql】使用变量实现类似oracle中lag函数功能
mysql使用变量实现类似oracle中的lag函数功能 说明: 有一个订单表,每次下单都会记录是否使用了券,现模拟一个需求,将订单表插入日志表达到记录用户上一次是否用券以及此订单是否用券的情况 #- ...
最新文章
- Mac下Android配置及unity3d的导出Android
- 一个简单的生产消费者示例
- 5加载stm32 keil_快速入门STM32单片机-软件篇
- 员工之间可不可以交流工资收入?
- 线程Java的两种方式_多线程(java和guava两种方式):
- MicroBlaze程序融合fpga的bit并烧写入Flash方法
- Android 4.X 系统加载 so 失败的原因分析
- 000 SpringMVC介绍
- 5毛钱搞一个2.4GHz射频信号探测器
- jquery.treeview.js php mysql,jquery.treeview应用
- L2-005 集合相似度(STL+暴力)
- DSP之直接存储器访问控制器
- linux mysql驱动在哪_MySQL驱动使用方法
- Vue人资中台--打包上线
- cos和sin转换公式
- 排列型枚举(座次问题)
- c语言实现mysql通配符_Mysql的C语言接口简单实现电话本功能
- python文件处理基础_第六篇:python基础之文件处理
- 服务器怎么安装php文档,云服务器php怎么安装
- 下载频道2013上半年超人气精华资源汇总---全都是免积分下载