continuous.md 2.1 KB
Newer Older
M
Mars Liu 已提交
1 2
# 获取连续区间

M
Mars Liu 已提交
3 4
SmartMarket 交易所的系统中,所有订单在生成时,都从一个 oracle Sequence 中获取唯一的 
序列号,完成交易计算后各个撮合程序将其插入如下的 orders 表中:
M
Mars Liu 已提交
5

M
Mars Liu 已提交
6
```mysql
M
Mars Liu 已提交
7 8 9
create table orders
(
    id      integer primary key,
M
Mars Liu 已提交
10
    content json
M
Mars Liu 已提交
11 12 13 14
    -- ignore other definitions...
);
```

M
Mars Liu 已提交
15 16 17 18 19
后续的结算系统需要连续的获取订单,以便处理一些顺序敏感的业务。但是撮合发生在很多个异步节
点上,它们只能保证最终会将所有订单都保存到 orders 表,确保 id 列最终是连续的,但是最新
插入的一段记录集有可能不连续。而我们希望结算系统成批的读取数据,以优化性能,那么在结算系
统有它最后处理的订单id的前提下,下面哪一个查询可以确保从这个id向前读取 id 连续 的一批
订单?
M
Mars Liu 已提交
20

M
Mars Liu 已提交
21 22
<hr/>

M
Mars Liu 已提交
23
点击进入[MySQL实战练习环境](https://mydev.csdn.net/product/pod/new?image=cimg-centos7-skilltreemysql&connect=auto&create=auto&utm_source=skill)
M
Mars Liu 已提交
24 25
* `show databases` 列出所有数据库
* `show tables` 列出所有表
M
Mars Liu 已提交
26

M
Mars Liu 已提交
27 28
## 答案

M
Mars Liu 已提交
29
```mysql
M
Mars Liu 已提交
30 31 32 33 34 35 36
with recursive r(id) as (select id
                         from orders
                         where id = $1
                         union
                         select d.id
                         from orders as d
                                  join r on d.id = r.id + 1)
M
Mars Liu 已提交
37
select orders.id, content
M
Mars Liu 已提交
38 39 40 41 42 43 44 45 46 47 48 49
from orders
         join r on orders.id = r.id;
```

## 选项

### A

没有办法构造一个简单查询实现这个功能,因为它的数据过滤条件递归的依赖查询结果。

### B

M
Mars Liu 已提交
50 51
```mysql
select data.id, content
M
Mars Liu 已提交
52 53 54 55 56 57 58
from orders
         join orders as r on orders.id = r.id - 1
where id = $1;
```

### C

M
Mars Liu 已提交
59 60
```mysql
select id, content
M
Mars Liu 已提交
61 62 63 64 65 66
from orders
where id in (select id from orders where id = id + 1);
```

### D

M
Mars Liu 已提交
67
```mysql
M
Mars Liu 已提交
68 69 70 71 72 73 74
with r as (select id
           from orders
           where id = $1
           union
           select d.id
           from orders as d
                    join r on d.id = r.id + 1)
M
Mars Liu 已提交
75
select orders.id, content
M
Mars Liu 已提交
76 77 78
from orders
         join r on orders.id = r.id;
```