专栏首页SQL实现SQL 获取上一个订单的状态

SQL 获取上一个订单的状态

问题描述

有一个订单表 t_order,有关 t_order 的描述见下表。

字段

类型

描述

id

Integer

主键

create_ts

Datetime

创建时间

uid

Integer

用户ID

is_suc

Integer

订单状态 1-成功 0-失败

t_order 的数据如下:

    id  create_ts               uid  is_suc  
------  -------------------  ------  --------
     1  2020-01-01 11:21:24       1         1
     2  2020-01-02 20:41:10       1         0
     3  2020-01-03 8:12:14        1         0
     4  2020-01-04 22:50:24       2         1
     5  2020-01-05 6:39:45        1         0
     6  2020-01-06 19:10:51       2         0
     7  2020-01-07 14:12:40       1         1
     8  2020-01-08 17:12:10       2         1
     9  2020-01-09 23:22:52       1         0
    10  2020-01-10 5:10:28        2         0

现在要做的是在 t_order 表中增加一列 last_id,用于展示上一个状态为“成功”的订单的 id,若找不到符合条件的订单,则 last_id 为 NULL

最终要实现的结果如下:

    id  create_ts               uid  is_suc  last_id  
------  -------------------  ------  ------  ---------
     1  2020-01-01 11:21:24       1       1     (NULL)
     2  2020-01-02 20:41:10       1       0          1
     3  2020-01-03 8:12:14        1       0          1
     4  2020-01-04 22:50:24       2       1     (NULL)
     5  2020-01-05 6:39:45        1       0          1
     6  2020-01-06 19:10:51       2       0          4
     7  2020-01-07 14:12:40       1       1          1
     8  2020-01-08 17:12:10       2       1          4
     9  2020-01-09 23:22:52       1       0          7
    10  2020-01-10 5:10:28        2       0          8

解决方案

需要明确的是,相对于当前订单的“上一个订单”是依据创建时间来选择,而不是主键。

暂时假设 t_order 中每个用户的订单的创建时间对应着主键单调递增,那我们就可以说最靠近当前订单的创建时间的记录就是要锁定的上一个订单。

要得到当前订单的上一个状态为“成功”的订单,可使用下面的 SQL 获取:

SELECT
  MAX(id)
FROM
  t_order
WHERE is_suc = 1
  AND uid = 当前订单的所属用户
  AND create_ts < 当前订单的创建时间

完整的 SQL 如下:

SELECT
  *,
  (SELECT
    MAX(id)
  FROM
    t_order
  WHERE is_suc = 1
    AND uid = a.uid
    AND create_ts < a.create_ts ) AS last_id
FROM
  t_order a

我们前面做了一个假设,假设每个用户的订单的创建时间是随着主键递增的,但有时候并不是这样。有的订单的创建得比较早,但是进入到数据库比较晚,因此就会出现在两条订单记录中,ID 较小的记录的创建时间比 ID 大的记录的创建时间还要晚的情况。如果是这种情况,就不能应用上面的 SQL 。

可以先筛选出小于当前订单的创建时间的所有记录,重新排序后只取创建时间最大的那条记录。

用 SQL 来表示:

SELECT
  id
FROM
  t_order
WHERE is_suc = 1
  AND uid = 当前订单的所属用户
  AND create_ts < 当前订单的创建时间
ORDER BY create_ts DESC
LIMIT 1

完整的 SQL:

SELECT
  *,
  (SELECT
    id
  FROM
    t_order
  WHERE is_suc = 1
    AND uid = a.uid
    AND create_ts < a.create_ts
  ORDER BY create_ts DESC
  LIMIT 1) AS last_id
FROM
  t_order a

本文分享自微信公众号 - SQL实现(gh_684ee9235a26),作者:zero

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-08-21

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 一道初级ETL BI的笔试题

    今天收到一个朋友发来的初级ETL BI 的笔试题,我觉得题目蛮有意思的,于是拿出来和大家分享。

    白日梦想家
  • SQL 打印全年日历

    上文我们实现了“打印一个月日历”的需求,今天在原来的基础实现一个更复杂的需求:打印一年的日历。

    白日梦想家
  • 如何删除重复数据(二)

    上一篇我们介绍了在有主键的表中删除重复数据,今天就介绍如何删除没有主键的表的重复数据。

    白日梦想家
  • Mongodb副本集+分片集群环境部署记录

    前面详细介绍了mongodb的副本集和分片的原理,这里就不赘述了。下面记录Mongodb副本集+分片集群环境部署过程: MongoDB Sharding Clu...

    洗尽了浮华
  • 五分钟shell系列第三节-海量数据topk问题

    假如该数据是是个整数 long 类型 在64位 sizeof(long)=8 字节, 一亿个记录占用内存=762M (一亿一个记录占用内存762M) 一个...

    程序员小王
  • Log4j 入门教程

    Log4J 是 Apache 的一个开源项目,通过在项目中使用 Log4J,我们可以控制日志信息输出到控制台、文件、GUI 组件、甚至是数据库中。我们可以控制每...

    Remember_Ray
  • 杨校老师课堂之JavaScript案例之跑马灯左右无缝连接图片自动轮播

            1.3 中间区域盒子中使用无序列表进行排放图片,并且每个图片可以作为一个链接进行点击

    杨校
  • 福特将为新公司投入40亿美元,主要负责自动驾驶汽车业务

    福特已经创建了Ford Autonomous Vehicles有限责任公司,将负责自动驾驶系统集成、自主汽车研发、先进工程、AV传输即服务网络开发、用户体验、业...

    AiTechYun
  • web端口实现文件下载到本地(Blob ,createElementNS)

    var ev = document.createEvent("MouseEvents");

    小布丁
  • 191. 位1的个数

    编写一个函数,输入是一个无符号整数,返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量)。

    lucifer210

扫码关注云+社区

领取腾讯云代金券