今天突然想到了一个需求,即在一张带有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查询两条记录的时间差的更多相关文章

  1. SQLServer 分组查询相邻两条记录的时间差

    原文:SQLServer 分组查询相邻两条记录的时间差 首先,我们通过数据库中表的两条记录来引出问题,如下图 以上为一个记录操作记录的表数据.OrderID为自增长列,后面依次为操作类型,操作时间,操 ...

  2. hive实现根据用户分组,按用户记录求上下两条记录的时间差

    在mysql,数据如下:#查询某一用户该日抽奖时间 select draw_time from user_draw_log where user_id = 1 and draw_date='2016- ...

  3. sql查询某条记录

    select * from (SELECT t.*,ROWNUM AS RN FROM AWARDISSUE_FOOTBALL t ORDER BY ID DESC) WHERE RN=2

  4. SQL查找TCar表中同一辆车前后两条记录的CarId,两条记录中有多个字段值一样

    查询同一个表中某一字段值相同的记录 select * from 表名 where 字段 in(select 字段 from 表名 group by 字段 having count(1)>1) s ...

  5. SQL查询多条不重复记录值简要解析【转载】

    转载http://hi.baidu.com/my_favourate/item/3716b0cbe125f312505058eb SQL查询多条不重复记录值简要解析2008-02-28 11:36 以 ...

  6. 【面经】面试官:如何以最高的效率从MySQL中随机查询一条记录?

    写在前面 MySQL数据库在互联网行业使用的比较多,有些小伙伴可能会认为MySQL数据库比较小,存储不了很多的数据.其实,这些小伙伴是真的不了解MySQL.MySQL的小不是说使用MySQL存储的数据 ...

  7. sqlserver -- 学习笔记(七)获取同组数据的前两条记录

    不啰嗦,直接上图,大概实现效果如下: 有上面这样一份数据,将他们按照userAccount和submitTime进行分组,然后提前每组数据的前两条记录 提取后数据如下: 实现的SQL如下: selec ...

  8. mysql 查询一条记录的下一条和上一条记录

    如果ID是主键或者有索引,可以直接查找: 方法一: 查询上一条记录的SQL语句(如果有其他的查询条件记得加上other_conditions以免出现不必要的错误): select * from tab ...

  9. mysql结构相同的三张表查询一条记录\将一张表中的数据插入另外一张表

    将一张表中的数据插入另外一张表 1.两张表结构相同 insert into 表1名称 select * from 表2名称 2.两张结构不相同的表 insert into 表1名称(列名1,列名2,列 ...

随机推荐

  1. HttpClient(二)-- 模拟浏览器抓取网页

    一.设置请求头消息 User-Agent模拟浏览器 1.当使用第一节的代码 来 访问推酷的时候,会返回给我们如下信息: 网页内容:<!DOCTYPE html> <html> ...

  2. 64位Oracle 11g 使用PL/SQL

    Oracle 11g和PL/SQL安装完后,发现打开PL/SQL并不能连接Oracle数据库! [第一回合]完败! 先是在网上找解决方法,说是需要使用Net Configuration Assista ...

  3. iOS UIImage:获取图片主色调

    本文转载至 http://www.wahenzan.com/a/mdev/ios/2015/0325/1677.html -(UIColor*)mostColor{ #if __IPHONE_OS_V ...

  4. vue案例 - 使用vue实现自定义多选与单选的答题功能

    4月底立得flag,五月底插上小旗,结果拖到六月底七月初才来执行.说什么工作忙都是借口,就是睡的比猪早,起的比猪晚. 本来实现多选单选这个功能,vue组件中在表单方面提供了一个v-model指令,非常 ...

  5. key是数字的对象集合

    整理如下: let data = {3: '影视', 4: '音乐', 5: '广场舞', 6: '游戏', 7: '综艺', 8: '动漫', 9: '翻唱', 10: '生活', 11: '美食' ...

  6. sencha touch list + carousel scrollable(与其他控件共用滚动条)

    有些时候我们需要实现这种效果 上边是一张图片或者一个跑马灯控件,这个布局实现起来比较容易 但是如何让他们共用一个滚动条,来实现以下效果就比较麻烦了. 在官方论坛查找资料得知,可以用以下写法实现: /* ...

  7. 2-5 vue基础语法

    一.vue基础语法 语法: {{msg}} html赋值: v-html="" 绑定属性: v-bind:id="" 使用表达式: {{ok? "ye ...

  8. RDMA卡的检测方法

    1. udaddy This script covers RDMA_CM UD connections. (It establishes a set of unreliable RDMA datagr ...

  9. 【咸鱼教程】TextureMerger1.6.6 一:Egret MovieClip的制作和使用

    几个月没写代码了.然后突然用到TextureMerger,发现不会用序列图做动画了... 于是写下过程,以防忘记... MovieClip主要是用于游戏中的动画制作和播放.支持swf.gif.序列图等 ...

  10. Unity3D笔记 GUI 四、实现选项卡三

    一.代码: using UnityEngine; using System.Collections; /// <summary> /// 选项卡二 /// </summary> ...