You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by ja...@apache.org on 2023/02/24 07:53:46 UTC

[iotdb] branch master updated: Modify Group-By UserGuide

This is an automated email from the ASF dual-hosted git repository.

jackietien pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/master by this push:
     new 06bb621a99 Modify Group-By UserGuide
06bb621a99 is described below

commit 06bb621a99a8d7cdcdf4d4793a89a66f6a8329a2
Author: YangCaiyin <yc...@gmail.com>
AuthorDate: Fri Feb 24 15:53:39 2023 +0800

    Modify Group-By UserGuide
---
 .../org/apache/iotdb/db/qp/sql/IdentifierParser.g4 |  2 +-
 .../org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4   |  2 +-
 .../antlr4/org/apache/iotdb/db/qp/sql/SqlLexer.g4  |  8 ++--
 docs/UserGuide/Query-Data/Group-By.md              | 45 +++++++++++++---------
 docs/UserGuide/Query-Data/Overview.md              |  4 +-
 docs/zh/UserGuide/Query-Data/Group-By.md           | 43 +++++++++++++--------
 docs/zh/UserGuide/Query-Data/Overview.md           |  4 +-
 ...ySeriesIT.java => IoTDBGroupByConditionIT.java} | 42 ++++++++++----------
 .../iotdb/db/mpp/plan/parser/ASTVisitor.java       |  2 +-
 9 files changed, 84 insertions(+), 68 deletions(-)

diff --git a/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IdentifierParser.g4 b/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IdentifierParser.g4
index 0a620a8e99..5889464db9 100644
--- a/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IdentifierParser.g4
+++ b/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IdentifierParser.g4
@@ -53,6 +53,7 @@ keyWords
     | CLEAR
     | CLUSTER
     | CONCAT
+    | CONDITION
     | CONFIGNODES
     | CONFIGURATION
     | CONTINUOUS
@@ -154,7 +155,6 @@ keyWords
     | RUNNING
     | SCHEMA
     | SELECT
-    | SERIES
     | SERIESSLOTID
     | SESSION
     | SET
diff --git a/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 b/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
index 4359ec507c..7a8c008ef5 100644
--- a/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
+++ b/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
@@ -481,7 +481,7 @@ groupByAttributeClause
     | LEVEL operator_eq INTEGER_LITERAL (COMMA INTEGER_LITERAL)*
     | TAGS LR_BRACKET identifier (COMMA identifier)* RR_BRACKET
     | VARIATION LR_BRACKET expression (COMMA delta=number)? (COMMA attributePair)? RR_BRACKET
-    | SERIES LR_BRACKET expression (COMMA expression)? (COMMA attributePair)? RR_BRACKET
+    | CONDITION LR_BRACKET expression (COMMA expression)? (COMMA attributePair)? RR_BRACKET
     | SESSION LR_BRACKET timeInterval=DURATION_LITERAL RR_BRACKET
     ;
 
diff --git a/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlLexer.g4 b/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlLexer.g4
index 0b1a1ca6bc..24ba612b93 100644
--- a/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlLexer.g4
+++ b/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlLexer.g4
@@ -129,6 +129,10 @@ CONCAT
     : C O N C A T
     ;
 
+CONDITION
+    : C O N D I T I O N
+    ;
+
 CONFIGNODES
     : C O N F I G N O D E S
     ;
@@ -554,10 +558,6 @@ SELECT
     : S E L E C T
     ;
 
-SERIES
-    : S E R I E S
-    ;
-
 SERIESSLOTID
     : S E R I E S S L O T I D
     ;
diff --git a/docs/UserGuide/Query-Data/Group-By.md b/docs/UserGuide/Query-Data/Group-By.md
index a817b0afc9..81ef77567a 100644
--- a/docs/UserGuide/Query-Data/Group-By.md
+++ b/docs/UserGuide/Query-Data/Group-By.md
@@ -587,7 +587,9 @@ As this feature is still under development, some queries have not been completed
 ## Aggregation By Variation
 IoTDB supports grouping by continuous stable values through the `GROUP BY VARIATION` statement.
 
-If the data remains stable in a range of given threshold over a period of time, the data point will be grouped together and execute aggregation query. The groups won't overlap and there is no fixed start time and end time.
+Group-By-Variation wil set the first point in group as the base point,  
+then if the difference between the new data and base point is small than or equal to delta, 
+the data point will be grouped together and execute aggregation query (The calculation of difference and the meaning of delte are introduced below). The groups won't overlap and there is no fixed start time and end time.
 The syntax of clause is as follows:
 ```sql
 group by variation(controlExpression[,delta][,ignoreNull=true/false])
@@ -595,20 +597,23 @@ group by variation(controlExpression[,delta][,ignoreNull=true/false])
 The different parameters mean:
 * controlExpression
 
-The value that is used when grouping data. It can be any columns or the expression of them.
+The value that is used to calculate difference. It can be any columns or the expression of them.
 * delta
 
-The threshold that is used when grouping. The difference of expression between the first data point and new data point should less than or equal to delta. When delta is zero, all the continuous data points with equal expression value will be grouped into the same group.
+The threshold that is used when grouping. The difference of controlExpression between the first data point and new data point should less than or equal to delta. 
+When delta is zero, all the continuous data with equal expression value will be grouped into the same group.
 * ignoreNull
 
 Used to specify how to deal with the data when the value of controlExpression is null. When ignoreNull is false, null will be treated as a new value and when ignoreNull is true, the data point will be directly skipped.
 
 The supported return types of controlExpression and how to deal with null value when ignoreNull is false are shown in the following table:
 
-|delta| supported return type of controlExpression | the handling of null when ignoreNull is false                                                                                                                                                                             |
-|-----|------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-|delta!=0| INT32、INT64、FLOAT、DOUBLE                       | If the processing group doesn't contains null, null value should be treated as infinity/infinitesimal and will end current group.<br/>Continuous null values are treated as stable values and assigned to the same group. | 
-|delta=0| TEXT、BINARY、INT32、INT64、FLOAT、DOUBLE           | Null is treated as a new value in a new group and continuous nulls belong to the same group.                                                                                                                              |            
+| delta    | Return Type Supported By controlExpression | The Handling of null when ignoreNull is False                                                                                                                                                                             |
+|----------|--------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| delta!=0 | INT32、INT64、FLOAT、DOUBLE                   | If the processing group doesn't contains null, null value should be treated as infinity/infinitesimal and will end current group.<br/>Continuous null values are treated as stable values and assigned to the same group. | 
+| delta=0  | TEXT、BINARY、INT32、INT64、FLOAT、DOUBLE       | Null is treated as a new value in a new group and continuous nulls belong to the same group.                                                                                                                              |            
+
+<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto; margin-right:auto; display:block;" src="https://raw.githubusercontent.com/apache/iotdb-bin-resources/main/docs/UserGuide/Process-Data/GroupBy/groupByVariation.jpeg" alt="groupByVariation">
 
 ### Precautions for Use
 1. The result of controlExpression should be a unique value. If multiple columns appear after using wildcard stitching, an error will be reported.
@@ -653,7 +658,7 @@ Get the result below which ignores the row with null value in `s6`.
 ```
 when ignoreNull is false, the row with null value in `s6` will be considered.
 ```sql
-select __endTime, avg(s1), count(s2), sum(s3) from root.sg.d group by variation(s6,ignoreNull=false)
+select __endTime, avg(s1), count(s2), sum(s3) from root.sg.d group by variation(s6, ignoreNull=false)
 ```
 Get the following result.
 ```
@@ -673,7 +678,7 @@ Get the following result.
 
 The sql is shown below:
 ```sql
-select __endTime, avg(s1), count(s2), sum(s3) from root.sg.d group by variation(s6+, 4)
+select __endTime, avg(s1), count(s2), sum(s3) from root.sg.d group by variation(s6, 4)
 ```
 Get the result below:
 ```
@@ -702,16 +707,16 @@ Get the result below:
 +-----------------------------+---------+-----------------+-------------------+-----------------+
 ```
 
-## Aggregation By Series
+## Aggregation By Condition
 When you need to filter the data according to a specific condition and group the continuous ones for an aggregation query.
-`GROUP BY SERIES` is suitable for you.The rows which don't meet the given condition will be simply ignored because they don't belong to any group.
+`GROUP BY CONDITION` is suitable for you.The rows which don't meet the given condition will be simply ignored because they don't belong to any group.
 Its syntax is defined below:
 ```sql
-group by series(predict,[keep>/>=/=/<=/<]threshold,[,ignoreNull=true/false])
+group by condition(predict,[keep>/>=/=/<=/<]threshold,[,ignoreNull=true/false])
 ```
 * predict
 
-Any legal expression return the type of boolean for filtering in groupinng.
+Any legal expression return the type of boolean for filtering in grouping.
 * [keep>/>=/=/<=/<]threshold
 
 Keep expression is used to specify the number of continuous rows that meet the `predict` condition to form a group. Only the number of rows in group satisfy the keep condition, the result of group will be output.
@@ -723,8 +728,9 @@ Used to specify how to handle data rows that encounter null predict, skip the ro
 ### Precautions for Use
 1. keep condition is required in the query, but you can omit the 'keep' string and given a constant which defaults to 'keep=constant' condition.
 2. IgnoreNull defaults to true.
-3. For a group in resultSet, the time column output the start time of the group by defalut. __endTime can be used in select clause to output the endTime of groups in resultSet.
+3. For a group in resultSet, the time column output the start time of the group by default. __endTime can be used in select clause to output the endTime of groups in resultSet.
 4. Each device is grouped separately when used with `ALIGN BY DEVICE`.
+5. Currently `GROUP BY CONDITION` is not supported with `GROUP BY LEVEL`.
 
 For the following raw data, several query examples are given below:
 ```
@@ -745,7 +751,7 @@ For the following raw data, several query examples are given below:
 ```
 The sql statement to query data with at least two continuous row shown below: 
 ```sql
-select __endTime,max_time(charging_status),count(vehicle_status),last_value(soc) from root.** group by series(charging_status=1,KEEP>=2,ignoringNull=true)
+select __endTime,max_time(charging_status),count(vehicle_status),last_value(soc) from root.** group by condition(charging_status=1,KEEP>=2,ignoringNull=true)
 ```
 Get the result below:
 ```
@@ -758,7 +764,7 @@ Get the result below:
 ```
 When ignoreNull is false, the null value will be treated as a row that doesn't meet the condition.
 ```sql
-select __endTime,max_time(charging_status),count(vehicle_status),last_value(soc) from root.** group by series(charging_status=1,KEEP>=2,ignoringNull=false)
+select __endTime,max_time(charging_status),count(vehicle_status),last_value(soc) from root.** group by condition(charging_status=1,KEEP>=2,ignoringNull=false)
 ```
 Get the result below, the original group is split.
 ```
@@ -784,11 +790,12 @@ A given interval threshold to create a new group of data when the difference bet
 
 The figure below is a grouping diagram under `GROUP BY SESSION`.
 
-<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto; margin-right:auto; display:block;" src="https://raw.githubusercontent.com/apache/iotdb-bin-resources/main/docs/UserGuide/Process-Data/GroupBy/SessionGroup.jpg">
+<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto; margin-right:auto; display:block;" src="https://raw.githubusercontent.com/apache/iotdb-bin-resources/main/docs/UserGuide/Process-Data/GroupBy/groupBySession.jpeg" alt="groupBySession">
 
 ### Precautions for Use
-1. For a group in resultSet, the time column output the start time of the group by defalut. __endTime can be used in select clause to output the endTime of groups in resultSet.
+1. For a group in resultSet, the time column output the start time of the group by default. __endTime can be used in select clause to output the endTime of groups in resultSet.
 2. Each device is grouped separately when used with `ALIGN BY DEVICE`.
+3. Currently `GROUP BY SESSION` is not supported with `GROUP BY LEVEL`.
 
 For the raw data below, a few query examples are given:
 ```
@@ -835,7 +842,7 @@ Get the result:
 ```
 It can be also used with `HAVING` and `ALIGN BY DEVICE` clauses.
 ```sql
-select __endTime,sum(hardware) from root.ln.wf02.wt01 group by session(50s) align by device
+select __endTime,sum(hardware) from root.ln.wf02.wt01 group by session(50s) having sum(hardware)>0 align by device
 ```
 Get the result below:
 ```
diff --git a/docs/UserGuide/Query-Data/Overview.md b/docs/UserGuide/Query-Data/Overview.md
index 3cb72cb0f6..4239baea47 100644
--- a/docs/UserGuide/Query-Data/Overview.md
+++ b/docs/UserGuide/Query-Data/Overview.md
@@ -35,7 +35,7 @@ SELECT [LAST] selectExpr [, selectExpr] ...
         LEVEL = levelNum [, levelNum] ... |
         TAGS(tagKey [, tagKey] ... )
         VARIATION(expression[,delta][,ignoreNull=true/false])|
-        SERIES(expression,[keep>/>=/=/</<=]threshold[,ignoreNull=true/false])|
+        CONDITION(expression,[keep>/>=/=/</<=]threshold[,ignoreNull=true/false])|
         SESSION(timeInterval)
     }]
     [HAVING havingCondition]
@@ -76,7 +76,7 @@ SELECT [LAST] selectExpr [, selectExpr] ...
 ### `GROUP BY` clause
 
 - The `GROUP BY` clause specifies how the time series are aggregated by segment or group.
-- Segmented aggregation refers to segmenting data in the row direction according to the time dimension, aiming at the time relationship between different data points in the same time series, and obtaining an aggregated value for each segment. Currently only **segmentation by time interval**、**group by variation**、**group by series** and **group by session** is supported, and more segmentation methods will be supported in the future.
+- Segmented aggregation refers to segmenting data in the row direction according to the time dimension, aiming at the time relationship between different data points in the same time series, and obtaining an aggregated value for each segment. Currently only **segmentation by time interval**、**group by variation**、**group by condition** and **group by session** is supported, and more segmentation methods will be supported in the future.
 - Group aggregation refers to grouping the potential business attributes of time series for different time series. Each group contains several time series, and each group gets an aggregated value. Support **group by path level** and **group by tag** two grouping methods.
 - Segment aggregation and group aggregation can be mixed.
 - For details and examples, see the document [Group By Aggregation](./Group-By.md).
diff --git a/docs/zh/UserGuide/Query-Data/Group-By.md b/docs/zh/UserGuide/Query-Data/Group-By.md
index e3b9f386ae..8562687f68 100644
--- a/docs/zh/UserGuide/Query-Data/Group-By.md
+++ b/docs/zh/UserGuide/Query-Data/Group-By.md
@@ -570,30 +570,37 @@ SELECT AVG(temperature) FROM root.factory1.** GROUP BY ([1000, 10000), 5s), TAGS
 > 5. 暂不支持聚合函数内部包含表达式,例如 `count(s+1)`。
 > 6. 不支持值过滤条件聚合,和分层聚合查询行为保持一致。
 
-## 事件分段聚合
-IoTDB支持通过`GROUP BY VARIATION`语句根据连续稳定值进行分组。时间序列数据在一段时间内如果保持在某个值的上下范围内浮动,在这个阈值内,将值大致相同的连续数据点归为一组。该分组方式不会重叠,且没有固定的开始结束事件。其子句语法如下:
+## 差值分段聚合
+IoTDB支持通过`GROUP BY VARIATION`语句来根据差值进行分组。`GROUP BY VARIATION`会将第一个点作为一个组的**基准点**,每个新的数据在按照给定规则与基准点进行差值运算后,
+如果差值小于给定的阈值则将该新点归于同一组,否则结束当前分组,以这个新的数据为新的基准点开启新的分组。
+该分组方式不会重叠,且没有固定的开始结束时间。其子句语法如下:
 ```sql
 group by variation(controlExpression[,delta][,ignoreNull=true/false])
 ```
 不同的参数含义如下 
 * controlExpression
 
-分组所参照的值,可以是查询数据中的某一列或是多列的表达式。 
+分组所参照的值,**可以是查询数据中的某一列或是多列的表达式
+(多列表达式计算后仍为一个值,使用多列表达式时指定的列必须都为数值列)**, 差值便是根据数据的controlExpression的差值运算。
 * delta
 
-分组所使用的阈值,同一分组中每条数据expression对应的值与第一个的差值都小于`delta`。当`delta=0`时,相当于一个等值分组,所有连续且expression值相同的数据将被分到一组。
+分组所使用的阈值,同一分组中**每个点的controlExpression对应的值与该组中基准点对应值的差值都小于`delta`**。当`delta=0`时,相当于一个等值分组,所有连续且expression值相同的数据将被分到一组。
 
 * ignoreNull
 
-用于指定`controlExpression`的计算返回值为null时对数据的处理方式,当`ignoreNull`为false时,null值会被视为新的值,`ignoreNull`为true时,则直接跳过对应的数据。
+用于指定`controlExpression`的值为null时对数据的处理方式,当`ignoreNull`为false时,该null值会被视为新的值,`ignoreNull`为true时,则直接跳过对应的点。
 
 在`delta`取不同值时,`controlExpression`支持的返回数据类型以及当`ignoreNull`为false时对于null值的处理方式可以见下表:
 
-| delta    | 支持的controlExpression的返回类型            | ignoreNull=false时对于Null值的处理                                     |
+| delta    | controlExpression支持的返回类型             | ignoreNull=false时对于Null值的处理                                     |
 |----------|--------------------------------------|-----------------------------------------------------------------|
-| delta!=0 | INT32、INT64、FLOAT、DOUBLE             | 若正在维护分组的值不为null,null视为无穷大/无穷小,结束当前分组。连续的null视为相等稳定的值,会被分配在同一个分组 |
+| delta!=0 | INT32、INT64、FLOAT、DOUBLE             | 若正在维护分组的值不为null,null视为无穷大/无穷小,结束当前分组。连续的null视为差值相等的值,会被分配在同一个分组 |
 | delta=0  | TEXT、BINARY、INT32、INT64、FLOAT、DOUBLE | null被视为新分组中的新值,连续的null属于相同的分组                                   |
 
+下图为差值分段的一个分段方式示意图,与组中第一个数据的控制列值的差值在delta内的控制列对应的点属于相同的分组。
+
+<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto; margin-right:auto; display:block;" src="https://raw.githubusercontent.com/apache/iotdb-bin-resources/main/docs/UserGuide/Process-Data/GroupBy/groupByVariation.jpeg" alt="groupByVariation">
+
 ### 使用注意事项
 1. `controlExpression`的结果应该为唯一值,如果使用通配符拼接后出现多列,则报错。
 2. 对于一个分组,默认Time列输出分组的开始时间,查询时可以使用select `__endTime`的方式来使得结果输出分组的结束时间。
@@ -637,7 +644,7 @@ select __endTime, avg(s1), count(s2), sum(s3) from root.sg.d group by variation(
 ```
 当指定ignoreNull为false时,会将s6为null的数据也考虑进来
 ```sql
-select __endTime, avg(s1), count(s2), sum(s3) from root.sg.d group by variation(s6,ignoreNull=false)
+select __endTime, avg(s1), count(s2), sum(s3) from root.sg.d group by variation(s6, ignoreNull=false)
 ```
 得到如下的结果
 ```
@@ -656,7 +663,7 @@ select __endTime, avg(s1), count(s2), sum(s3) from root.sg.d group by variation(
 ### delta!=0时的差值事件分段
 使用如下sql语句
 ```sql
-select __endTime, avg(s1), count(s2), sum(s3) from root.sg.d group by variation(s6+, 4)
+select __endTime, avg(s1), count(s2), sum(s3) from root.sg.d group by variation(s6, 4)
 ```
 得到如下的查询结果
 ```
@@ -684,11 +691,11 @@ select __endTime, avg(s1), count(s2), sum(s3) from root.sg.d group by variation(
 |1970-01-01T08:00:00.090+08:00|      150|             80.5|                  2|            180.0|
 +-----------------------------+---------+-----------------+-------------------+-----------------+
 ```
-## 事件条件分段聚合
-当需要根据指定条件对数据行进行筛选,并将连续的数据分为一组进行聚合运算时,可以使用`GROUP BY SERIES`的分段方式;不满足的给定条件的行因为不属于任何分组会被直接简单忽略。
+## 条件分段聚合
+当需要根据指定条件对数据进行筛选,并将连续的符合条件的行分为一组进行聚合运算时,可以使用`GROUP BY CONDITION`的分段方式;不满足给定条件的行因为不属于任何分组会被直接简单忽略。
 其语法定义如下:
 ```sql
-group by series(predict,[keep>/>=/=/<=/<]threshold,[,ignoreNull=true/false])
+group by condition(predict,[keep>/>=/=/<=/<]threshold,[,ignoreNull=true/false])
 ```
 * predict
 
@@ -702,10 +709,11 @@ keep表达式用来指定形成分组所需要连续满足`predict`条件的数
 用于指定遇到predict为null的数据行时的处理方式,为true则跳过该行,为false则结束当前分组。
 
 ### 使用注意事项
-1. keep条件在查询中是必需的,但可以省略掉'keep'字符串给出一个常数,默认为`keep=该常数`的等于条件。
+1. keep条件在查询中是必需的,但可以省略掉keep字符串给出一个常数,默认为`keep=该常数`的等于条件。
 2. `ignoreNull`默认为true。
 3. 对于一个分组,默认Time列输出分组的开始时间,查询时可以使用select `__endTime`的方式来使得结果输出分组的结束时间。
 4. 与`ALIGN BY DEVICE`搭配使用时会对每个device进行单独的分组操作。
+5. 当前暂不支持与`GROUP BY LEVEL`搭配使用。
 
 
 对于如下原始数据,下面会给出几个查询样例:
@@ -727,7 +735,7 @@ keep表达式用来指定形成分组所需要连续满足`predict`条件的数
 ```
 查询至少连续两行以上的charging_status=1的数据,sql语句如下:
 ```sql
-select __endTime,max_time(charging_status),count(vehicle_status),last_value(soc) from root.** group by series(charging_status=1,KEEP>=2,ignoringNull=true)
+select __endTime,max_time(charging_status),count(vehicle_status),last_value(soc) from root.** group by condition(charging_status=1,KEEP>=2,ignoringNull=true)
 ```
 得到结果如下:
 ```
@@ -740,7 +748,7 @@ select __endTime,max_time(charging_status),count(vehicle_status),last_value(soc)
 ```
 当设置`ignoreNull`为false时,遇到null值为将其视为一个不满足条件的行,会结束正在计算的分组。
 ```sql
-select __endTime,max_time(charging_status),count(vehicle_status),last_value(soc) from root.** group by series(charging_status=1,KEEP>=2,ignoringNull=false)
+select __endTime,max_time(charging_status),count(vehicle_status),last_value(soc) from root.** group by condition(charging_status=1,KEEP>=2,ignoringNull=false)
 ```
 得到如下结果,原先的分组被含null的行拆分:
 ```
@@ -764,11 +772,12 @@ group by session(timeInterval)
 
 下图为`group by session`下的一个分组示意图
 
-<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto; margin-right:auto; display:block;" src="https://raw.githubusercontent.com/apache/iotdb-bin-resources/main/docs/UserGuide/Process-Data/GroupBy/SessionGroup.jpg">
+<img style="width:100%; max-width:800px; max-height:600px; margin-left:auto; margin-right:auto; display:block;" src="https://raw.githubusercontent.com/apache/iotdb-bin-resources/main/docs/UserGuide/Process-Data/GroupBy/groupBySession.jpeg" alt="groupBySession">
 
 ### 使用注意事项
 1. 对于一个分组,默认Time列输出分组的开始时间,查询时可以使用select `__endTime`的方式来使得结果输出分组的结束时间。
 2. 与`ALIGN BY DEVICE`搭配使用时会对每个device进行单独的分组操作。
+3. 当前暂不支持与`GROUP BY LEVEL`搭配使用。
 
 对于下面的原始数据,给出几个查询样例。
 ```
@@ -815,7 +824,7 @@ select __endTime,count(*) from root.** group by session(1d)
 ```
 也可以和`HAVING`、`ALIGN BY DEVICE`共同使用
 ```sql
-select __endTime,sum(hardware) from root.ln.wf02.wt01 group by session(50s) align by device
+select __endTime,sum(hardware) from root.ln.wf02.wt01 group by session(50s) having sum(hardware)>0 align by device
 ```
 得到如下结果,其中排除了`sum(hardware)`为0的部分
 ```
diff --git a/docs/zh/UserGuide/Query-Data/Overview.md b/docs/zh/UserGuide/Query-Data/Overview.md
index a38ead27e8..c393831bbb 100644
--- a/docs/zh/UserGuide/Query-Data/Overview.md
+++ b/docs/zh/UserGuide/Query-Data/Overview.md
@@ -35,7 +35,7 @@ SELECT [LAST] selectExpr [, selectExpr] ...
         LEVEL = levelNum [, levelNum] ... |
         TAGS(tagKey [, tagKey] ... |
         VARIATION(expression[,delta][,ignoreNull=true/false])|
-        SERIES(expression,[keep>/>=/=/</<=]threshold[,ignoreNull=true/false])|
+        CONDITION(expression,[keep>/>=/=/</<=]threshold[,ignoreNull=true/false])|
         SESSION(timeInterval)
     }]
     [HAVING havingCondition]
@@ -76,7 +76,7 @@ SELECT [LAST] selectExpr [, selectExpr] ...
 ### `GROUP BY` 子句
 
 - `GROUP BY` 子句指定对序列进行分段或分组聚合的方式。
-- 分段聚合是指按照时间维度,针对同时间序列中不同数据点之间的时间关系,对数据在行的方向进行分段,每个段得到一个聚合值。目前支持**按时间区间分段**、**按事件分段**、**按事件条件分段**和**按会话时间分段**,未来将支持更多分段方式。
+- 分段聚合是指按照时间维度,针对同时间序列中不同数据点之间的时间关系,对数据在行的方向进行分段,每个段得到一个聚合值。目前支持**时间区间分段**、**差值分段**、**条件分段**和**会话分段**,未来将支持更多分段方式。
 - 分组聚合是指针对不同时间序列,在时间序列的潜在业务属性上分组,每个组包含若干条时间序列,每个组得到一个聚合值。支持**按路径层级分组**和**按序列标签分组**两种分组方式。
 - 分段聚合和分组聚合可以混合使用。
 - 详细说明及示例见文档 [分段分组聚合](./Group-By.md) 。
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/groupby/IoTDBGroupBySeriesIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/groupby/IoTDBGroupByConditionIT.java
similarity index 93%
rename from integration-test/src/test/java/org/apache/iotdb/db/it/groupby/IoTDBGroupBySeriesIT.java
rename to integration-test/src/test/java/org/apache/iotdb/db/it/groupby/IoTDBGroupByConditionIT.java
index e26c39c82d..4c30e76013 100644
--- a/integration-test/src/test/java/org/apache/iotdb/db/it/groupby/IoTDBGroupBySeriesIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/groupby/IoTDBGroupByConditionIT.java
@@ -42,7 +42,7 @@ import static org.junit.Assert.fail;
 
 @RunWith(IoTDBTestRunner.class)
 @Category({LocalStandaloneIT.class, ClusterIT.class})
-public class IoTDBGroupBySeriesIT {
+public class IoTDBGroupByConditionIT {
   // the data can be viewed in
   // https://docs.google.com/spreadsheets/d/1vsSmb41pdmK-BdBR1STwr8olg1Qc8baKVEWnfJB4mAg/edit#gid=0
   private static final String[] SQLs =
@@ -140,7 +140,7 @@ public class IoTDBGroupBySeriesIT {
   }
 
   @Test
-  public void groupBySeriesTest1() {
+  public void groupByConditionTest1() {
     String[][] res =
         new String[][] {
           {"1", "2", "1.0", "2", "16.0"},
@@ -150,53 +150,53 @@ public class IoTDBGroupBySeriesIT {
           {"2400000000", "2500000000", "100000000.0", "2", "100.0"}
         };
     String sql =
-        "select __endTime,max_time(charging_status) - min_time(charging_status),count(vehicle_status),last_value(soc) from root.sg.beijing.car01 group by series(charging_status=1,KEEP>=2,ignoreNull=false)";
+        "select __endTime,max_time(charging_status) - min_time(charging_status),count(vehicle_status),last_value(soc) from root.sg.beijing.car01 group by condition(charging_status=1,KEEP>=2,ignoreNull=false)";
     normalTestWithEndTime(res, sql);
     String sql2 =
-        "select max_time(charging_status) - min_time(charging_status),count(vehicle_status),last_value(soc) from root.sg.beijing.car01 group by series(charging_status=1,KEEP>=2,ignoreNull=false)";
+        "select max_time(charging_status) - min_time(charging_status),count(vehicle_status),last_value(soc) from root.sg.beijing.car01 group by condition(charging_status=1,KEEP>=2,ignoreNull=false)";
     normalTest(res, sql2);
   }
 
   @Test
-  public void groupBySeriesTest2() {
+  public void groupByConditionTest2() {
     String[][] res =
         new String[][] {
           {"1", "2", "1.0", "2", "16.0"},
           {"5", "2500000000", "2499999995.0", "9", "100.0"}
         };
     String sql =
-        "select __endTime,max_time(charging_status) - min_time(charging_status),count(vehicle_status),last_value(soc) from root.sg.beijing.car01 group by series(charging_status=1,KEEP>=2,ignoreNull=true)";
+        "select __endTime,max_time(charging_status) - min_time(charging_status),count(vehicle_status),last_value(soc) from root.sg.beijing.car01 group by condition(charging_status=1,KEEP>=2,ignoreNull=true)";
     normalTestWithEndTime(res, sql);
     String sql2 =
-        "select max_time(charging_status) - min_time(charging_status),count(vehicle_status),last_value(soc) from root.sg.beijing.car01 group by series(charging_status=1,KEEP>=2,ignoreNull=true)";
+        "select max_time(charging_status) - min_time(charging_status),count(vehicle_status),last_value(soc) from root.sg.beijing.car01 group by condition(charging_status=1,KEEP>=2,ignoreNull=true)";
     normalTest(res, sql2);
   }
 
   @Test
-  public void groupBySeriesTest3() {
+  public void groupByConditionTest3() {
     String[][] res =
         new String[][] {
           {"5", "2500000000", "2499999995.0", "9", "100.0"},
         };
     String sql =
-        "select __endTime,max_time(charging_status) - min_time(charging_status),count(vehicle_status),last_value(soc) from root.sg.beijing.car01 group by series(charging_status=1,KEEP>=3,ignoreNull=true)";
+        "select __endTime,max_time(charging_status) - min_time(charging_status),count(vehicle_status),last_value(soc) from root.sg.beijing.car01 group by condition(charging_status=1,KEEP>=3,ignoreNull=true)";
     normalTestWithEndTime(res, sql);
     String sql2 =
-        "select max_time(charging_status) - min_time(charging_status),count(vehicle_status),last_value(soc) from root.sg.beijing.car01 group by series(charging_status=1,KEEP>=3,ignoreNull=true)";
+        "select max_time(charging_status) - min_time(charging_status),count(vehicle_status),last_value(soc) from root.sg.beijing.car01 group by condition(charging_status=1,KEEP>=3,ignoreNull=true)";
     normalTest(res, sql2);
   }
 
   @Test
-  public void groupBySeriesTest4() {
+  public void groupByConditionTest4() {
     String[][] res =
         new String[][] {
           {"5", "7", "2.0", "3", "36.0"},
         };
     String sql =
-        "select __endTime,max_time(charging_status) - min_time(charging_status),count(vehicle_status),last_value(soc) from root.sg.beijing.car01 group by series(charging_status=1,KEEP>=3,ignoreNull=false)";
+        "select __endTime,max_time(charging_status) - min_time(charging_status),count(vehicle_status),last_value(soc) from root.sg.beijing.car01 group by condition(charging_status=1,KEEP>=3,ignoreNull=false)";
     normalTestWithEndTime(res, sql);
     String sql2 =
-        "select max_time(charging_status) - min_time(charging_status),count(vehicle_status),last_value(soc) from root.sg.beijing.car01 group by series(charging_status=1,KEEP>=3,ignoreNull=false)";
+        "select max_time(charging_status) - min_time(charging_status),count(vehicle_status),last_value(soc) from root.sg.beijing.car01 group by condition(charging_status=1,KEEP>=3,ignoreNull=false)";
     normalTest(res, sql2);
   }
 
@@ -337,22 +337,22 @@ public class IoTDBGroupBySeriesIT {
   }
 
   @Test
-  public void groupBySeriesTestAlignByDevice() {
+  public void groupByConditionTestAlignByDevice() {
     String[][] res =
         new String[][] {
           {"1", "2", "1.0", "2", "16.0"},
           {"5", "2500000000", "2499999995.0", "9", "100.0"}
         };
     String sql =
-        "select __endTime,max_time(charging_status) - min_time(charging_status),count(vehicle_status),last_value(soc) from root.** group by series(charging_status=1,KEEP>=2,ignoreNull=true) align by device";
+        "select __endTime,max_time(charging_status) - min_time(charging_status),count(vehicle_status),last_value(soc) from root.** group by condition(charging_status=1,KEEP>=2,ignoreNull=true) align by device";
     normalTestWithEndTimeAlignByDevice(res, sql);
     String sql2 =
-        "select max_time(charging_status) - min_time(charging_status),count(vehicle_status),last_value(soc) from root.** group by series(charging_status=1,KEEP>=2,ignoreNull=true) align by device";
+        "select max_time(charging_status) - min_time(charging_status),count(vehicle_status),last_value(soc) from root.** group by condition(charging_status=1,KEEP>=2,ignoreNull=true) align by device";
     normalTestAlignByDevice(res, sql2);
   }
 
   @Test
-  public void groupBySeriesTestWithHaving() {
+  public void groupByConditionTestWithHaving() {
     String[][] res =
         new String[][] {
           {"9", "10", "1.0", "2", "60.0"},
@@ -360,18 +360,18 @@ public class IoTDBGroupBySeriesIT {
           {"2400000000", "2500000000", "100000000.0", "2", "100.0"}
         };
     String sql =
-        "select __endTime,max_time(charging_status) - min_time(charging_status),count(vehicle_status),last_value(soc) from root.sg.beijing.car01 group by series(charging_status=1,KEEP>=2,ignoreNull=false) having last_value(soc)>50";
+        "select __endTime,max_time(charging_status) - min_time(charging_status),count(vehicle_status),last_value(soc) from root.sg.beijing.car01 group by condition(charging_status=1,KEEP>=2,ignoreNull=false) having last_value(soc)>50";
     normalTestWithEndTime(res, sql);
     String sql2 =
-        "select max_time(charging_status) - min_time(charging_status),count(vehicle_status),last_value(soc) from root.sg.beijing.car01 group by series(charging_status=1,KEEP>=2,ignoreNull=false) having last_value(soc)>50";
+        "select max_time(charging_status) - min_time(charging_status),count(vehicle_status),last_value(soc) from root.sg.beijing.car01 group by condition(charging_status=1,KEEP>=2,ignoreNull=false) having last_value(soc)>50";
     normalTest(res, sql2);
   }
 
   @Test
-  public void groupBySeriesFirstValueTest() {
+  public void groupByConditionFirstValueTest() {
     String[][] res = new String[][] {{"5", "7", "18.0"}};
     String sql =
-        "select __endTime,first_value(soc) from root.sg.beijing.car01 group by series(charging_status!=0,KEEP>2,ignoreNull=false)";
+        "select __endTime,first_value(soc) from root.sg.beijing.car01 group by condition(charging_status!=0,KEEP>2,ignoreNull=false)";
     try (Connection connection = EnvFactory.getEnv().getConnection();
         Statement statement = connection.createStatement()) {
 
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java
index dced126e8c..2a80908424 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java
@@ -966,7 +966,7 @@ public class ASTVisitor extends IoTDBSqlParserBaseVisitor<Statement> {
           groupByKeys.add("COMMON");
           queryStatement.setGroupByComponent(
               parseGroupByClause(groupByAttribute, WindowType.EVENT_WINDOW));
-        } else if (groupByAttribute.SERIES() != null) {
+        } else if (groupByAttribute.CONDITION() != null) {
           if (groupByKeys.contains("COMMON")) {
             throw new SemanticException(GROUP_BY_COMMON_ONLY_ONE_MSG);
           }