---
source_url: https://docs.dolphindb.cn/zh/progr/sql/exe_order.html
fetched_at: 2026-05-19T09:04:05Z
category: progr
title: 执行顺序
sha1: c4f417a82664775ece4b5fc69ea2b7ec7a22e0a4
---

# 执行顺序

在 DolphinDB 中，SQL 语句各部分的执行顺序大致与其它系统中 SQL 一致。特别需要注意的是当使用
`context by` 子句时，`csort` 关键字或 `limit` /
`top` 子句的执行顺序。

以下为 DolphinDB 中 SQL 语句各部分的执行顺序：

1. `from` 子句

   `from` 子句中的表对象或者 lj，ej，aj 等表连接，会最先被执行。
2. `on` 子句

   `on` 子句会对 `from` 子句应用 `on`
   筛选，只保留符合连接条件的行。如果指定了 `left join(lj)`，`right join`
   等外连接，那么保留表中未匹配的行作为外部行添加到 `on` 子句产生的临时表中。
3. `where` 条件

   不符合 `where` 过滤条件的行会被舍弃。

   注：

   - 仅可处理 `from` 子句中的数据，不可使用 `select` 子句中不属于
     `from` 子句对象的新列名，例如通过 `as`
     进行重命名的列、计算结果列。
   - `where` 子句中使用 "," 或 "and" 时，执行顺序不同：由 ","
     连接的条件，将从左到右依次进行过滤，即先过滤最左边的条件，然后对临时结果表继续过滤下一个相邻的条件，直至过滤完最后一个条件，得到最终的结果表；而由
     "and" 连接的条件，将对所有条件基于原表过滤后再将结果取交集。
4. `group by` / `context by` /
   `pivot by` 子句

   经过 `where` 条件过滤的行会依据 `group by`
   / `context by` / `pivot by` 子句进行分组。
5. `csort` 关键字（仅为 `context by`
   子句提供）

   `context by` 通常与时间序列函数一起使用，每个分组中行的顺序对结果有直接影响。在
   `context by` 子句后使用 `csort`
   关键字，对每个组内的数据进行排序。

   注：

   只有配合序列相关函数、聚合函数、having 子句或 limit 子句一同使用时，csort 才会对组内数据执行排序。
6. `having` 条件（若使用了`group by` /
   `context by` 子句）

   若使用了`group by` / `context by`
   子句，则对每组使用 `having` 条件过滤，不满足条件的组被舍弃。与 `where`
   条件相同，`having` 条件中亦不可使用 `select` 子句中不属于
   `from` 子句对象的新列名，例如计算结果。
7. `select` 子句

   若 `select` 子句指定了计算，此时才执行。
8. `distinct` 子句

   去除 `select` 子句中重复的记录。
9. `limit` / `top` 子句
   （若使用了`context by` 子句）

   若使用了`context by` 子句，`limit` /
   `top` 子句应用于每组。若有 n 组且 `limit` m 或
   `top` m，则最多返回 n\*m 行。 此情况下 `limit` /
   `top` 子句的执行顺序是在 `order by` 子句之前；其它情况下的
   `limit` / `top` 子句的执行顺序是在 `order
   by` 子句之后。
10. `order by` 子句

    由于 `order by` 子句的执行顺序在 `select`
    子句之后，`order by` 子句可使用 `select` 子句中不属于
    `from` 子句对象的新列名，例如计算结果。
11. `limit` / `top` 子句 （若未使用
    `context by` 子句）

    若未使用 `context by` 子句，则 `limit` /
    `top` 子句应用于前一步的全体结果，其指定范围之外的行被丢弃。

    *特殊情况*：`cgroup by` 子句

    若 SQL 语句使用 `cgroup by`
    子句，其执行顺序如下：首先使用过滤条件（若有），然后根据 `cgroup by` 的列与 `group
    by` 的列（若有），对 `select` 子句中的项目进行分组计算，然后根据 `order
    by` 的列（必须使用，且必须属于 `group by` 列或 `cgroup
    by` 列）对分组计算结果进行排序，最后计算累计值。若使用 `group by`，则在每个
    `group by` 组内计算累计值。

## 例子

```dolphindb
t = table(1 1 1 1 1 2 2 2 2 2 as id, 09:30:00+1 3 2 5 4 5 2 4 3 1 as time, 1 2 3 4 5 6 5 4 3 2 as x);
t;
```

| id | time | x |
| --- | --- | --- |
| 1 | 09:30:01 | 1 |
| 1 | 09:30:03 | 2 |
| 1 | 09:30:02 | 3 |
| 1 | 09:30:05 | 4 |
| 1 | 09:30:04 | 5 |
| 2 | 09:30:05 | 6 |
| 2 | 09:30:02 | 5 |
| 2 | 09:30:04 | 4 |
| 2 | 09:30:03 | 3 |
| 2 | 09:30:01 | 2 |

```dolphindb
select *, deltas(x) from t context by id;
```

| id | time | x | deltas\_x |
| --- | --- | --- | --- |
| 1 | 09:30:01 | 1 |  |
| 1 | 09:30:03 | 2 | 1 |
| 1 | 09:30:02 | 3 | 1 |
| 1 | 09:30:05 | 4 | 1 |
| 1 | 09:30:04 | 5 | 1 |
| 2 | 09:30:05 | 6 |  |
| 2 | 09:30:02 | 5 | -1 |
| 2 | 09:30:04 | 4 | -1 |
| 2 | 09:30:03 | 3 | -1 |
| 2 | 09:30:01 | 2 | -1 |

```dolphindb
select *, deltas(x) from t context by id csort time;
```

| id | time | x | deltas\_x |
| --- | --- | --- | --- |
| 1 | 09:30:01 | 1 |  |
| 1 | 09:30:02 | 3 | 2 |
| 1 | 09:30:03 | 2 | -1 |
| 1 | 09:30:04 | 5 | 3 |
| 1 | 09:30:05 | 4 | -1 |
| 2 | 09:30:01 | 2 |  |
| 2 | 09:30:02 | 5 | 3 |
| 2 | 09:30:03 | 3 | -2 |
| 2 | 09:30:04 | 4 | 1 |
| 2 | 09:30:05 | 6 | 2 |

以上结果说明，使用 csort time 后，首先在每组中按照 time 排序，然后计算
`deltas(x)`。

```dolphindb
select *, deltas(x) from t context by id csort time limit 3;
```

| id | time | x | deltas\_x |
| --- | --- | --- | --- |
| 1 | 09:30:01 | 1 |  |
| 1 | 09:30:02 | 3 | 2 |
| 1 | 09:30:03 | 2 | -1 |
| 2 | 09:30:01 | 2 |  |
| 2 | 09:30:02 | 5 | 3 |
| 2 | 09:30:03 | 3 | -2 |

以上结果说明，若使用了`context by` 与 `limit`
子句，`limit` 子句应用于每组，而非全体结果。

```dolphindb
select *, deltas(x) from t context by id csort time order by id, deltas_x desc;
```

| id | time | x | deltas\_x |
| --- | --- | --- | --- |
| 1 | 09:30:04 | 5 | 3 |
| 1 | 09:30:02 | 3 | 2 |
| 1 | 09:30:03 | 2 | -1 |
| 1 | 09:30:05 | 4 | -1 |
| 1 | 09:30:01 | 1 |  |
| 2 | 09:30:02 | 5 | 3 |
| 2 | 09:30:05 | 6 | 2 |
| 2 | 09:30:04 | 4 | 1 |
| 2 | 09:30:03 | 3 | -2 |
| 2 | 09:30:01 | 2 |  |

以上结果说明，因为 `order by` 子句的执行顺序在
`select` 子句之后，所以 `order by` 子句中可以使用
`select` 子句中的计算结果 deltas\_x。

```dolphindb
select *, deltas(x) from t context by id csort time order by id, deltas_x desc limit 3;
```

| id | time | x | deltas\_x |
| --- | --- | --- | --- |
| 1 | 09:30:02 | 3 | 2 |
| 1 | 09:30:03 | 2 | -1 |
| 1 | 09:30:01 | 1 |  |
| 2 | 09:30:02 | 5 | 3 |
| 2 | 09:30:03 | 3 | -2 |
| 2 | 09:30:01 | 2 |  |

以上结果说明，若使用了`context by` 子句，`limit`
子句限制每组内的行数，且在 `order by` 子句之前执行。

```dolphindb
select * from t order by id, x desc limit 3;
```

| id | time | x |
| --- | --- | --- |
| 1 | 09:30:04 | 5 |
| 1 | 09:30:05 | 4 |
| 1 | 09:30:02 | 3 |

以上结果说明，若未使用 `context by` 子句，`limit`
子句限制全体结果的行数，且在 `order by` 子句之后执行。

```dolphindb
select *, deltas(x) from t where x>=3 context by id;
```

| id | time | x | deltas\_x |
| --- | --- | --- | --- |
| 1 | 09:30:02 | 3 |  |
| 1 | 09:30:05 | 4 | 1 |
| 1 | 09:30:04 | 5 | 1 |
| 2 | 09:30:05 | 6 |  |
| 2 | 09:30:02 | 5 | -1 |
| 2 | 09:30:04 | 4 | -1 |
| 2 | 09:30:03 | 3 | -1 |

以上结果说明，`where` 条件的执行顺序在 `select`
子句之前。以上语句中，先执行 `where x>=3`，再计算
`deltas(x)`，所以每只股票结果中的第一行 deltas\_x 的结果为空。

```dolphindb
select *, deltas(x) from t where x>=3 context by id having sum(x)<=12;
```

| id | time | x | deltas\_x |
| --- | --- | --- | --- |
| 1 | 09:30:02 | 3 |  |
| 1 | 09:30:05 | 4 | 1 |
| 1 | 09:30:04 | 5 | 1 |

以上结果说明，`having` 条件的执行顺序在 `where`
条件之后。
