sql查询两条记录的时间差
今天突然想到了一个需求,即在一张带有id和time字段的表中,查询相邻时间的时间差。
- 表的记录如下:
表名为wangxin

id是一个不重复的字符串,time是一个时间戳。
- 现在的需求如下:
比如id分别有wangxin1到wangxin4的几个椅子,小王同学,先坐上wangxin1的椅子,然后坐了几秒后,又坐到了编号为wangxin2的椅子上,然后一会儿又换到了wangxin3的椅子上,最后坐到wangxin4的椅子上,问,分别在每一个椅子上坐的时间。最后一个默认为0.
- 需求解决思路
想要知道差值,那就意味着必须把时间都比一下,可是只有一张表怎么办,就只能使用子查询的方式,利用内连接,获取到笛卡尔积,即一个时间点对应四个时间点,这样一来,就方便对其进行一个运算了。
-- 第一步,创建笛卡尔积
SELECT
w1.*, w2.*
FROM
wangxin w1
INNER JOIN (SELECT w3.time FROM wangxin w3) w2 ;
使用内连接的方式创建笛卡尔积,如下所示,这是用来方便计算两个时间点的差值的:

-- 第二步,进行运算
SELECT
w1.id, w1.time,w2.time-w1.time as time_diff
FROM
wangxin w1
INNER JOIN (SELECT w3.time FROM wangxin w3) w2 ;

这一步运算就是为了计算出两次的时间差,可见,我们需要的是相近时间点的差值,并且因为是差值,所以只能大于0,故我们第三步整理中,以上一步的结果作为一个新的表,再进行一次select操作,同时我们以time字段分组,并且取time_diff字段非0以外的最小值。
-- 第三步,整理
SELECT
t1.id,
t1.time,
MIN(t1.time_diff) AS time_diff
FROM
(
SELECT
w1.id,
w1.time,
w2.time - w1.time AS time_diff
FROM
wangxin w1
INNER JOIN (SELECT w3.time FROM wangxin w3) w2
) t1
WHERE
t1.time_diff > 0
GROUP BY
t1.time

这时候,我们发现了咦,为什么wangxin4这个记录没有了,原来是因为我们上面采用的是时间差大于0的情况,由于wangxin4后面就没有新的时间戳了,所以无法计算时间差,故其时间差为0,在上一步的where语句中被略去。
最后我们再加上一不外链接
-- 加回原来的表中
SELECT
t.*, IFNULL(t2.time_diff, 0) as '时间差'
FROM
wangxin t
LEFT JOIN (
SELECT
t1.id,
t1.time,
MIN(t1.time_diff) AS time_diff
FROM
(
SELECT
w1.id,
w1.time,
w2.time - w1.time AS time_diff
FROM
wangxin w1
INNER JOIN (SELECT w3.time FROM wangxin w3) w2
) t1
WHERE
t1.time_diff > 0
GROUP BY
t1.time
) t2 ON t.id = t2.id
这一步外链接里面需要注意的是,因为上一次的表中没有id为wangxin4这个记录,所以在左外链接的情况下,就会变成null,因此我们在select语句中,需要对这种情况做一个判断,判断是否为null,如果是null的话,就让这个单元格设置为0
最终结果为:

结果和想象中的一样。
总结:
之前一直觉得sql很简单,随便写写就行了,但是今天接触了一个非常复杂的sql,顿时觉得自己先前真的太幼稚了,sql相对于java更贴近算法,从书写到优化,发现sql是一门非常厉害的技术,自愧不如、自愧不如哇!
需要学习的东西还很多,与君共勉!
sql查询两条记录的时间差的更多相关文章
- SQLServer 分组查询相邻两条记录的时间差
原文:SQLServer 分组查询相邻两条记录的时间差 首先,我们通过数据库中表的两条记录来引出问题,如下图 以上为一个记录操作记录的表数据.OrderID为自增长列,后面依次为操作类型,操作时间,操 ...
- hive实现根据用户分组,按用户记录求上下两条记录的时间差
在mysql,数据如下:#查询某一用户该日抽奖时间 select draw_time from user_draw_log where user_id = 1 and draw_date='2016- ...
- sql查询某条记录
select * from (SELECT t.*,ROWNUM AS RN FROM AWARDISSUE_FOOTBALL t ORDER BY ID DESC) WHERE RN=2
- SQL查找TCar表中同一辆车前后两条记录的CarId,两条记录中有多个字段值一样
查询同一个表中某一字段值相同的记录 select * from 表名 where 字段 in(select 字段 from 表名 group by 字段 having count(1)>1) s ...
- SQL查询多条不重复记录值简要解析【转载】
转载http://hi.baidu.com/my_favourate/item/3716b0cbe125f312505058eb SQL查询多条不重复记录值简要解析2008-02-28 11:36 以 ...
- 【面经】面试官:如何以最高的效率从MySQL中随机查询一条记录?
写在前面 MySQL数据库在互联网行业使用的比较多,有些小伙伴可能会认为MySQL数据库比较小,存储不了很多的数据.其实,这些小伙伴是真的不了解MySQL.MySQL的小不是说使用MySQL存储的数据 ...
- sqlserver -- 学习笔记(七)获取同组数据的前两条记录
不啰嗦,直接上图,大概实现效果如下: 有上面这样一份数据,将他们按照userAccount和submitTime进行分组,然后提前每组数据的前两条记录 提取后数据如下: 实现的SQL如下: selec ...
- mysql 查询一条记录的下一条和上一条记录
如果ID是主键或者有索引,可以直接查找: 方法一: 查询上一条记录的SQL语句(如果有其他的查询条件记得加上other_conditions以免出现不必要的错误): select * from tab ...
- mysql结构相同的三张表查询一条记录\将一张表中的数据插入另外一张表
将一张表中的数据插入另外一张表 1.两张表结构相同 insert into 表1名称 select * from 表2名称 2.两张结构不相同的表 insert into 表1名称(列名1,列名2,列 ...
随机推荐
- JSON XSS
漏洞实例一: 1.在更新用户信息,修改联系电话,抓包绕过前端20个字符限制,Payload为 111<img src=1 onerror=alert(1)> 2.更新后,访问json 3. ...
- 获取指定ip段的所有存活主机的主机名和操作系统
https://jingyan.baidu.com/article/ceb9fb1089fd948cad2ba000.html java探测局域网存活 https://blog.csdn.net/we ...
- ASP正则匹配方法
方法二:找到匹配的进行替换 ip="127.0.0.1" Function ReplaceTest(str,patrn, replStr) Dim regEx, str1 Set ...
- iOS开发-- 使用NSNumber将int、float、long等数据类型加入到数组或字典中
// 设置值 NSNumber *number=[NSNumber numberWithInt:45]; // 取值 NSLog(@"NSNumber %d",[number in ...
- RAC的搭建(三)--Grid的安装
1. 安装cvuqdisk.rpm补丁包 在两个Oracle RAC 所有节点上安装操作系统程序包cvuqdisk.如果没有cvuqdisk,集群验证实用程序就无法发现共享磁盘. 该包在p104045 ...
- mosquitto 参数配置
mosquitto 参数配置 1.retry_interval 当QoS为1或2的消息已经被发送后,mosquitto在一段时间内仍未接收到客户端的反馈消息,将重新发送消息. 默认为20秒 2.sy ...
- PHP MYSQL 分表方法
function get_hash_table($table,$uid){ $_str = crc32($uid); if($_str < 0 ){ $ret = "0".s ...
- SQL - 根据天来分组比较
SELECT COUNT(*) FROM (SELECT WeixinUserID,CONVERT(varchar(100),CreateTime, 23) AS DT FROM SiteVisite ...
- 【总结】redis和memcached的区别
1.Redis和Memcache都是将数据存放在内存中,都是内存数据库.不过memcache还可用于缓存其他东西,例如图片.视频等等: 2.Redis不仅仅支持简单的k/v类型的数据,同时还提供lis ...
- IE6/IE7/IE8下float:right的异常及其解决方法
1.最简单的方法就是调换顺序,将需要右浮动的元素写在前面.写成这样:<h2><a href="#">更多>></a>小标题</ ...