SQL 获取上一个订单的状态

时间:2022-07-24
本文章向大家介绍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