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,列 ...
随机推荐
- 导入贴图操作:处理贴图MaxSize和Format
using UnityEngine; using System.Collections; using UnityEditor; public class ImportModflyTextures : ...
- [SublimeText] 如何创建工程
Sublime Text 可以很方便地管理多个工程.使用Sublime Text的Projects,可以将不同根目录的文件组织起来成为一个工程,而不用将所有的文件都放到一个根目录下面. 1. 创建工程 ...
- Kafka producer拦截器(interceptor)
Producer拦截器(interceptor)是个相当新的功能,它和consumer端interceptor是在Kafka 0.10版本被引入的,主要用于实现clients端的定制化控制逻辑. 对于 ...
- 扩展方法以及LinQ的学习
我们今天学习的内容其实还是蛮多的,学习了自动属性,扩展方法,复习初始化器,以及LinQ的一些方法,其实感觉有些还是很熟悉的,在前面的学习过程中有时间感觉学习的知识知道了怎么使用,但是还没有在项目中使用 ...
- Englis - 英文字母和音标
英语学习基础基础是一切的根本 学习是一个长期积累知识的过程,正确掌握各科学习方法显得尤其重要!很多孩子学习成绩不好.记忆力不佳都是因为没有掌握正确的学习方法而造成的. 最基本的是:26个英文字母 48 ...
- 使用C#把发表的时间改为几个月,几天前,几小时前,几分钟前,或几秒前
//使用C#把发表的时间改为几个月,几天前,几小时前,几分钟前,或几秒前 //2008年03月15日 星期六 02:35 public string DateStringFromNow(DateTim ...
- 多了解一下Chrome开发者控制台
多了解一下Chrome开发者控制台 2017年10月14日 • Tools, Web前端 • 1.0k views • 暂无评论 作为一名前端开发者,Chrome内置的控制台是必须了解的,它拥有非常丰 ...
- session超时跃出iframe并跳到登陆页面(转载)
session超时跳出iframe并跳到登陆页面 在网页编程时,我们经常需要处理,当session过期时,我们要跳到登陆页面让用户登陆,由于我们可能用到IFrame框架,所以我们我登陆页面需要显示在整 ...
- Esper学习之十四:Pattern(一)
1. Pattern Atoms and Pattern operatorsPattern是通过原子事件和操作符组合在一起构成模板.原子事件有3类,操作符有4类,具体如下: 原子事件:1). 普通事件 ...
- 使用import取代require
首先,Module 语法是 JavaScript 模块的标准写法,坚持使用这种写法.使用import取代require. // bad const moduleA = require('moduleA ...