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

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

fix bug  
张志晨 已提交
6
```sql
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/>

F
feilong 已提交
23
点击进入[MySQL实战练习环境](https://mydev.csdn.net/product/pod/new?image=cimg-centos7-skilltreemysql&connect=auto&create=auto&utm_source=skill){target="_blank"}。
F
feilong 已提交
24

F
feilong 已提交
25 26
* `show databases;` 列出所有数据库
* `show tables;` 列出所有表
M
Mars Liu 已提交
27

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

fix bug  
张志晨 已提交
30
```sql
31 32 33 34 35 36 37 38
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 已提交
39
select orders.id, content
M
Mars Liu 已提交
40 41 42 43 44 45 46 47 48 49 50 51
from orders
         join r on orders.id = r.id;
```

## 选项

### A

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

### B

fix bug  
张志晨 已提交
52
```sql
M
Mars Liu 已提交
53
select data.id, content
54 55
from orders 
    join orders as r on orders.id = r.id - 1
M
Mars Liu 已提交
56 57 58 59 60
where id = $1;
```

### C

fix bug  
张志晨 已提交
61
```sql
M
Mars Liu 已提交
62
select id, content
M
Mars Liu 已提交
63
from orders
64 65 66 67
where id in (
    select id 
    from orders 
    where id = id + 1);
M
Mars Liu 已提交
68 69 70 71
```

### D

fix bug  
张志晨 已提交
72
```sql
M
Mars Liu 已提交
73 74 75 76 77 78 79
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 已提交
80
select orders.id, content
M
Mars Liu 已提交
81 82 83
from orders
         join r on orders.id = r.id;
```