diff --git a/docs/zh/openmldb_sql/deployment_manage/ONLINE_REQUEST_REQUIREMENTS.md b/docs/zh/openmldb_sql/deployment_manage/ONLINE_REQUEST_REQUIREMENTS.md
index 43b4c9e4941..1d402de8a2e 100644
--- a/docs/zh/openmldb_sql/deployment_manage/ONLINE_REQUEST_REQUIREMENTS.md
+++ b/docs/zh/openmldb_sql/deployment_manage/ONLINE_REQUEST_REQUIREMENTS.md
@@ -12,14 +12,23 @@ OpenMLDB仅支持上线[SELECT查询语句](../dql/SELECT_STATEMENT.md)。
下表列出了在线请求模式支持的 `SELECT` 子句。
-| SELECT 子句 | 说明 |
-|:-------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------|
-| 单张表的简单表达式计算 | 简单的单表查询是对一张表进行列运算、使用运算表达式或单行处理函数(Scalar Function)以及它们的组合表达式作计算。需要遵循[在线请求模式下单表查询的使用规范](#在线请求模式下单表查询的使用规范) |
-| [`JOIN` 子句](../dql/JOIN_CLAUSE.md) | OpenMLDB目前仅支持**LAST JOIN**。需要遵循[在线请求模式下LAST JOIN的使用规范](#在线请求模式下-last-join-的使用规范) |
+| SELECT 子句 | 说明 |
+| :--------------------------------------- | :----------------------------------------------------------- |
+| 无表查询 | SELECT 没有 FROM 子句, 只做表达式计算 |
+| 单张表的简单表达式计算 | 简单的单表查询是对一张表进行列运算、使用运算表达式或单行处理函数(Scalar Function)以及它们的组合表达式作计算。需要遵循[在线请求模式下单表查询的使用规范](#在线请求模式下单表查询的使用规范) |
+| [`JOIN` 子句](../dql/JOIN_CLAUSE.md) | OpenMLDB目前仅支持**LAST JOIN**。需要遵循[在线请求模式下LAST JOIN的使用规范](#在线请求模式下-last-join-的使用规范) |
| [`WINDOW` 子句](../dql/WINDOW_CLAUSE.md) | 窗口子句用于定义一个或者若干个窗口。窗口可以是有名或者匿名的。用户可以在窗口上调用聚合函数进行分析计算。需要遵循[在线请求模式下Window的使用规范](#在线请求模式下window的使用规范) |
## 在线请求模式下 `SELECT` 子句的使用规范
+### 无表查询
+
+```sql
+SELECT sin(30) as out;
+```
+
+
+
### 在线请求模式下单表查询的使用规范
- 仅支持列运算,表达式,以及单行处理函数(Scalar Function)以及它们的组合表达式运算。
@@ -57,15 +66,16 @@ SELECT substr(COL7, 3, 6) FROM t1;
### 在线请求模式下 `LAST JOIN` 的使用规范
-- 仅支持`LAST JOIN`类型。
-- 至少有一个JOIN条件是形如`left_source.column=right_source.column`的EQUAL条件,**并且`right_source.column`列需要命中右表的索引(key 列)**。
-- 带排序LAST JOIN的情况下,`ORDER BY`只支持单列的列引用表达式,列类型为 int16, int32, int64 or timestamp, **并且列需要命中右表索引的时间列**。
-- 右表 TableRef
+1. 仅支持`LAST JOIN`类型。
+2. 至少有一个JOIN条件是形如`left_source.column=right_source.column`的EQUAL条件,**并且`right_source.column`列需要命中右表的索引(key 列)**。
+3. 带排序LAST JOIN的情况下,`ORDER BY`只支持单列的列引用表达式,列类型为 int16, int32, int64 or timestamp, **并且列需要命中右表索引的时间列**。满足条件 2 和 3 的情况我们简单称做表能被 LAST JOIN 的 JOIN 条件优化
+4. 右表 TableRef
- 可以指一张物理表, 或者子查询语句
- 子查询情况, 只支持
- 简单列筛选 (`select * from tb` or `select id, val from tb`)
- 窗口聚合子查询, 例如 `select id, count(val) over w as cnt from t1 window w as (...)`. 这种情况下, 子查询和 last join 的左表必须有相同的主表, 主表指计划树下最左边的物理表节点.
- **Since OpenMLDB 0.8.0** 带 WHERE 条件过滤的简单列筛选 ( 例如 `select * from tb where id > 10`)
+ - **Since OpenMLDB 0.8.4** 右表是带 LAST JOIN 的子查询 `subquery`, 要求 `subquery` 最左的表能被 JOIN 条件优化, `subquery`剩余表能被自身 LAST JOIN 的 JOIN 条件优化
**Example: 支持上线的 `LAST JOIN` 语句范例**
创建两张表以供后续`LAST JOIN`。
@@ -115,15 +125,46 @@ desc t1;
t1.col0 as t1_col0,
t1.col1 + t2.col1 + 1 as test_col1,
FROM t1
- LAST JOIN t2 ORDER BY t2.std_time ON t1.col1=t2.col1;
+ LAST JOIN t2 ORDER BY t2.std_time ON t1.col1=t2.col1;
+```
+
+右表是带 LAST JOIN 或者 WHERE 条件过滤的情况
+
+```sql
+CREATE TABLE t3 (col0 STRING, col1 int, std_time TIMESTAMP, INDEX(KEY=col1, TS=std_time, TTL_TYPE=absolute, TTL=30d));
+-- SUCCEED
+
+SELECT
+ t1.col1 as t1_col1,
+ t2.col1 as t2_col1,
+ t2.col0 as t2_col0
+FROM t1 LAST JOIN (
+ SELECT * FROM t2 WHERE strlen(col0) > 0
+) t2
+ON t1.col1 = t2.col1
+
+-- t2 被 JOIN 条件 't1.col1 = tx.t2_co1l' 优化, t3 被 JOIN 条件 't2.col1 = t3.col1'
+SELECT
+ t1.col1 as t1_col1,
+ tx.t2_col1,
+ tx.t3_col1
+FROM t1 LAST JOIN (
+ SELECT t2.col1 as t2_col1, t3.col1 as t3_col1
+ FROM t2 LAST JOIN t3
+ ON t2.col1 = t3.col1
+) tx
+ON t1.col1 = tx.t2_col1
```
+
+
### 在线请求模式下Window的使用规范
- 窗口边界仅支持`PRECEDING`和`CURRENT ROW`
- 窗口类型仅支持`ROWS`和`ROWS_RANGE`。
- 窗口`PARTITION BY`只支持列表达式,可以是多列,并且所有列需要命中索引,主表和 union source 的表都需要符合要求
-- 窗口`ORDER BY`只支持列表达式,只能是单列,并且列需要命中索引的时间列,主表和 union source 的表都需要符合要求
+- 窗口`ORDER BY`只支持列表达式,只能是单列,并且列需要命中索引的时间列,主表和 union source 的表都需要符合要求. 从 OpenMLDB 0.8.4 开始, ORDER BY 可以不写, 但需要满足额外的要求, 详见 [WINDOW CLAUSE](../dql/WINDOW_CLAUSE.md)
+- **OpenMLDB 0.8.4 版本开始, 支持窗口定义不带 ORDER BY**, 具体要求如
- 可支持使用 `EXCLUDE CURRENT_ROW`,`EXCLUDE CURRENT_TIME`,`MAXSIZE`,`INSTANCE_NOT_IN_WINDOW`对窗口进行其他特殊限制,详见[OpenMLDB特有的 WindowSpec 元素](#openmldb特有的-windowspec-元素)。
- `WINDOW UNION` source 要求,支持如下格式的子查询:
- 表引用或者简单列筛选,例如 `t1` 或者 `select id, val from t1`。union source 和 主表的 schema 必须完全一致,并且 union source 对应的 `PARTITION BY`, `ORDER BY` 也需要命中索引
diff --git a/docs/zh/openmldb_sql/dql/WINDOW_CLAUSE.md b/docs/zh/openmldb_sql/dql/WINDOW_CLAUSE.md
index 18f49149429..c688f338527 100644
--- a/docs/zh/openmldb_sql/dql/WINDOW_CLAUSE.md
+++ b/docs/zh/openmldb_sql/dql/WINDOW_CLAUSE.md
@@ -119,7 +119,7 @@ partition key相等的所有行,还不是窗口,经由order by列排序后
## 基本的 WindowSpec 语法元素
-### Window Partition Clause 和 Window OrderBy Clause
+### WINDOW PARTITION BY clause 和 WINDOW ORDER BY clause
```sql
WindowPartitionClause
@@ -129,9 +129,18 @@ WindowOrderByClause
::= ( 'ORDER' 'BY' ByList )
```
-`PARTITION BY`选项将查询的行分为一组进入*partitions*, 这些行在窗口函数中单独处理。`PARTITION BY`和查询级别`GROUP BY` 子句做相似的工作,除了它的表达式只能作为表达式不能作为输出列的名字或数。OpenMLDB要求必须配置`PARTITION BY`。并且目前**仅支持按列分组**,无法支持按运算和函数表达式分组。
+`PARTITION BY`选项将查询的行分为一组进入*partitions*, 这些行在窗口函数中单独处理。`PARTITION BY`和查询级别`GROUP BY` 子句做相似的工作, 只是它只能作为表达式不能作为查询结果的输出列或输出列 ID。OpenMLDB要求必须配置`PARTITION BY`。PARTITION BY list 可以有多个, 但**仅支持按列分组**,无法支持按运算或函数表达式分组。
+
+`ORDER BY` 选项决定分区中的行被窗口函数处理的顺序。它和查询级别`ORDER BY`子句做相似的工作, 同样不能作为查询结果的输出列或者输出列 ID。OpenMLDB 目前**仅支持按列排序**,ORDER BY list 有且只能有一个, 不支持按运算或函数表达式排序。**OpenMLDB 0.8.4** 以后, ORDER BY 子句可以不写, 表示窗口内的列将以不确定的顺序处理, 不带 ORDER BY 子句需要满足如下条件:
+
+1. 不能有`EXCLUDE CURRENT_TIME`
+2. 对于 ROWS 类型窗口没有更多限制, 对于 ROWS_RANGE 类型窗口:
+ 1. 窗口 FRAME 的边界不能是 `offset [OPEN] PRECEDING/FOLLOWING` 的格式, 目前情况只能为 `UNBOUNDED PRECEDING AND CURRENT ROW`
+
+```{note}
+窗口不带 ORDER BY 的情况, 意味着对于在线预览模式, 计算结果是不确定的. 同时对于一些通用窗口函数, 例如 `lag, first_value`, 在所有模式下得到的计算结果都是不确定的.
+```
-`ORDER BY` 选项决定分区中的行被窗口函数处理的顺序。它和查询级别`ORDER BY`子句做相似的工作, 但是同样的它不能作为输出列的名字或数。同样,OpenMLDB要求必须配置`ORDER BY`。并且目前**仅支持按列排序**,无法支持按运算和函数表达式排序。
### Window Frame Clause
diff --git a/docs/zh/openmldb_sql/sql_difference.md b/docs/zh/openmldb_sql/sql_difference.md
index 3118f8f71bb..74405ee0894 100644
--- a/docs/zh/openmldb_sql/sql_difference.md
+++ b/docs/zh/openmldb_sql/sql_difference.md
@@ -81,7 +81,7 @@ WINDOW 子句和 GROUP BY & HAVING 子句不支持同时使用。上线时 WINDO
特殊限制:
-- 在线请求模式下,WINDOW 的输入是 LAST JOIN 或者子查询内的 LAST JOIN, 注意窗口的定义里 `PARTITION BY` & `ORDER BY` 的列都必须来自 JOIN 最左边的表。
+- 在线请求模式下,WINDOW 的输入是 LAST JOIN 或者带子查询内的 LAST JOIN, 注意窗口的定义里 `PARTITION BY` & `ORDER BY` 的列都必须来自 JOIN 最左边的表。
### GROUP BY & HAVING 子句
@@ -101,7 +101,7 @@ OpenMLDB 仅支持 LAST JOIN 一种 JOIN 语法,详细描述参考扩展语法
| **应用于** | **离线模式** | **在线预览模式** | **在线请求模式** |
| ------------------------------------------------------------ | ------------ | ---------------- | ---------------- |
| 两个表引用 | ✓ | ✕ | ✓ |
-| 子查询, 仅包括:
左右表均为简单列筛选
左右表为 WINDOW 或 LAST JOIN 操作 | ✓ | ✓ | ✓ |
+| 子查询, 仅包括:
左右表均为简单列筛选
左右表为 WINDOW 或 LAST JOIN 操作
带 WHERE 条件过滤的单表查询 | ✓ | ✓ | ✓ |
特殊限制:
@@ -118,7 +118,7 @@ OpenMLDB (>= v0.7.2) 支持非递归的 WITH 子句。WITH 子句等价于其它
### ORDER BY 关键字
-排序关键字 `ORDER BY` 仅在窗口定义 `WINDOW` 和拼表操作 `LAST JOIN` 子句内部被支持,并且不支持倒排序关键字 `DESC`。参见 WINDOW 子句和 LAST JOIN 子句内的相关说明。
+排序关键字 `ORDER BY` 仅在窗口定义 `WINDOW` 和拼表操作 `LAST JOIN` 子句内部被支持,并且不支持倒排序关键字 `DESC`。 OpenMLDB 0.8.4 以后支持窗口定义不带 ORDER BY, 但需额外满足特定条件. 参见 WINDOW 子句和 LAST JOIN 子句内的相关说明。
### 聚合函数
@@ -149,10 +149,10 @@ OpenMLDB 主要对 `WINDOW` 以及 `LAST JOIN` 语句进行了深度定制化开
| **语句元素** | **支持语法** | **说明** | **必需 ?** |
| ---------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ----------- |
| 数据定义 | PARTITION BY | 可支持多列
支持的列数据类型: bool, int16, int32, int64, string, date, timestamp | ✓ |
-| 数据排序 | ORDER BY | 仅支持对单一列排序
可支持数据类型: int16, int32, int64, timestamp
不支持倒序 `DESC` | ✓ |
+| 数据排序 | ORDER BY | 仅支持对单一列排序
可支持数据类型: int16, int32, int64, timestamp
不支持倒序 `DESC`
OpenMLDB 0.8.4 之前必填 | - |
| 范围定义 |
基本上下界定义语法:ROWS/ROWS_RANGE BETWEEN ... AND ...
支持范围定义关键字 PRECEDING, OPEN PRECEDING, CURRENT ROW, UNBOUNDED | 必须给定上下边界
不支持边界关键字 FOLLOWING
在线请求模式中,CURRENT ROW 为当前的请求行。在表格视角下,当前行将会被虚拟的插入到表格根据 ORDER BY 排序的正确位置上。 | ✓ |
-| 范围单位 | ROWS
ROWS_RANGE(扩展) | ROWS_RANGE 为扩展语法,其定义的窗口边界属性等价于标准 SQL 的 RANGE 类型窗口,支持用数值或者带时间单位的数值定义窗口边界,后者为拓展语法。
带时间单位定义的窗口范围,等价于时间转化成毫秒数值后的窗口定义。例如 `ROWS_RANGE 10s PRCEDING ...` 和 `ROWS_RANGE 10000 PRECEDNG ...` 是等价的。 | ✓ |
-| 窗口属性(扩展) | MAXSIZE
EXCLUDE CURRENT_ROW
EXCLUDE CURRENT_TIME
INSTANCE_NOT_IN_WINDOW | MAXSIZE 只对 ROWS_RANGE 有效 | - |
+| 范围单位 | ROWS
ROWS_RANGE(扩展) | ROWS_RANGE 为扩展语法,其定义的窗口边界属性等价于标准 SQL 的 RANGE 类型窗口,支持用数值或者带时间单位的数值定义窗口边界,后者为拓展语法。
带时间单位定义的窗口范围,等价于时间转化成毫秒数值后的窗口定义。例如 `ROWS_RANGE 10s PRCEDING ...` 和 `ROWS_RANGE 10000 PRECEDNG ...` 是等价的。 | ✓ |
+| 窗口属性(扩展) | MAXSIZE
EXCLUDE CURRENT_ROW
EXCLUDE CURRENT_TIME
INSTANCE_NOT_IN_WINDOW | MAXSIZE 只对 ROWS_RANGE 有效
不带 ORDER BY 和 EXCLUDE CURRENT_TIME 不能同时使用 | - |
| 多表定义(扩展) | 实际使用中语法形态较为复杂,参考:
[跨表特征开发教程](../tutorial/tutorial_sql_2.md)
[WINDOW UNION 语法文档](../openmldb_sql/dql/WINDOW_CLAUSE.md#1-window--union) | 允许合并多个表
允许联合简单子查询
实践中,一般和聚合函数搭配使用,实现跨表的聚合操作 | - |
| 匿名窗口 | - | 必须包括 PARTITION BY、ORDER BY、以及窗口范围定义 | - |