执行顺序
DolphinDB中,SQL语句各部分的执行顺序大致与其它系统中SQL一致。特别需要注意的是当使用context by子句时,csort关键字或limit / top子句的执行顺序。
以下为DolphinDB中SQL语句各部分的执行顺序:
1. from子句
from子句中的表对象或者 lj,ej,aj 等表连接,会最先被执行。
2. where条件
不符合where过滤条件的行会被舍弃。请注意,这一步仅可处理from子句中的数据,不可使用select子句中不属于from子句对象的新列名,例如计算结果。
3. group by / context by / pivot by子句
经过where条件过滤的行会依据 group by / context by / pivot by子句进行分组。
4. csort关键字(仅为 context by 子句提供)
context by通常与时间序列函数一起使用,每个分组中行的顺序对结果有直接影响。在context by子句后使用csort关键字,对每个组内的数据进行排序。
5. having 条件(若使用了group by / context by子句)
若使用了group by / context by 子句,则对每组使用having条件过滤,不满足条件的组被舍弃。与where条件相同,having条件中亦不可使用select子句中不属于from子句对象的新列名,例如计算结果。
6. select子句
若select子句指定了计算,此时才执行。
7. limit / top子句 (若使用了context by子句)
若使用了context by子句,limit / top 子句应用于每组。若有 n 组且 limit m 或 top m,则最多返回 n*m 行。 此情况下limit / top子句的执行顺序是在order by子句之前;其它情况下的limit / top子句的执行顺序是在order by子句之后。
8. order by子句
由于order by子句的执行顺序在select子句之后,order by子句可使用select子句中不属于from子句对象的新列名,例如计算结果。
9. 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组内计算累计值。
例子
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 |
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 |
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)。
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子句应用于每组,而非全体结果。
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。
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子句之前执行。
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子句之后执行。
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的结果为空。
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条件之后。