diff --git a/src/.vuepress/sidebar/V2.0.x/en-Table.ts b/src/.vuepress/sidebar/V2.0.x/en-Table.ts index 73eee9bcd..243fde378 100644 --- a/src/.vuepress/sidebar/V2.0.x/en-Table.ts +++ b/src/.vuepress/sidebar/V2.0.x/en-Table.ts @@ -238,10 +238,10 @@ export const enSidebar = { { text: 'SELECT Clause', link: 'Select-Clause_apache' }, { text: 'FROM&JOIN Clause', link: 'From-Join-Clause' }, { text: 'WHERE Clause', link: 'Where-Clause' }, - { text: 'GROUP BY Clause', link: 'GroupBy-Clause' }, + { text: 'GROUP BY Clause', link: 'GroupBy-Clause_apache' }, { text: 'HAVING Clause', link: 'Having-Clause' }, - { text: 'FILL Clause', link: 'Fill-Clause' }, - { text: 'ORDER BY Clause', link: 'OrderBy-Clause' }, + { text: 'FILL Clause', link: 'Fill-Clause_apache' }, + { text: 'ORDER BY Clause', link: 'OrderBy-Clause_apache' }, { text: 'LIMIT&OFFSET Clause', link: 'Limit-Offset-Clause' }, { text: 'Nested Queries', link: 'Nested-Queries' }, { text: 'Common Table Expressions (CTE)', link: 'Common-Table-Expression_apache' }, diff --git a/src/.vuepress/sidebar/V2.0.x/zh-Table.ts b/src/.vuepress/sidebar/V2.0.x/zh-Table.ts index a1f69708b..59cd1473e 100644 --- a/src/.vuepress/sidebar/V2.0.x/zh-Table.ts +++ b/src/.vuepress/sidebar/V2.0.x/zh-Table.ts @@ -238,10 +238,10 @@ export const zhSidebar = { { text: 'SELECT子句', link: 'Select-Clause_apache' }, { text: 'FROM&JOIN子句', link: 'From-Join-Clause' }, { text: 'WHERE子句', link: 'Where-Clause' }, - { text: 'GROUP BY子句', link: 'GroupBy-Clause' }, + { text: 'GROUP BY子句', link: 'GroupBy-Clause_apache' }, { text: 'HAVING子句', link: 'Having-Clause' }, - { text: 'FILL子句', link: 'Fill-Clause' }, - { text: 'ORDER BY子句', link: 'OrderBy-Clause' }, + { text: 'FILL子句', link: 'Fill-Clause_apache' }, + { text: 'ORDER BY子句', link: 'OrderBy-Clause_apache' }, { text: 'LIMIT&OFFSET子句', link: 'Limit-Offset-Clause' }, { text: '嵌套查询', link: 'Nested-Queries' }, { text: '公用表表达式(CTE)', link: 'Common-Table-Expression_apache' }, diff --git a/src/UserGuide/Master/Table/Basic-Concept/Query-Data_apache.md b/src/UserGuide/Master/Table/Basic-Concept/Query-Data_apache.md index 3f45018e6..8115e37d1 100644 --- a/src/UserGuide/Master/Table/Basic-Concept/Query-Data_apache.md +++ b/src/UserGuide/Master/Table/Basic-Concept/Query-Data_apache.md @@ -40,10 +40,10 @@ The IoTDB table model query syntax supports the following clauses: - **SELECT Clause**: Specifies the columns to be included in the result. Details: [SELECT Clause](../SQL-Manual/Select-Clause_apache.md) - **FROM Clause**: Indicates the data source for the query, which can be a single table, multiple tables joined using the `JOIN` clause, or a subquery. Details: [FROM & JOIN Clause](../SQL-Manual/From-Join-Clause.md) - **WHERE Clause**: Filters rows based on specific conditions. Logically executed immediately after the `FROM` clause. Details: [WHERE Clause](../SQL-Manual/Where-Clause.md) -- **GROUP BY Clause**: Used for aggregating data, specifying the columns for grouping. Details: [GROUP BY Clause](../SQL-Manual/GroupBy-Clause.md) +- **GROUP BY Clause**: Used for aggregating data, specifying the columns for grouping. Details: [GROUP BY Clause](../SQL-Manual/GroupBy-Clause_apache.md) - **HAVING Clause**: Applied after the `GROUP BY` clause to filter grouped data, similar to `WHERE` but operates after grouping. Details:[HAVING Clause](../SQL-Manual/Having-Clause.md) -- **FILL Clause**: Handles missing values in query results by specifying fill methods (e.g., previous non-null value or linear interpolation) for better visualization and analysis. Details:[FILL Clause](../SQL-Manual/Fill-Clause.md) -- **ORDER BY Clause**: Sorts query results in ascending (`ASC`) or descending (`DESC`) order, with optional handling for null values (`NULLS FIRST` or `NULLS LAST`). Details: [ORDER BY Clause](../SQL-Manual/OrderBy-Clause.md) +- **FILL Clause**: Handles missing values in query results by specifying fill methods (e.g., previous non-null value or linear interpolation) for better visualization and analysis. Details:[FILL Clause](../SQL-Manual/Fill-Clause_apache.md) +- **ORDER BY Clause**: Sorts query results in ascending (`ASC`) or descending (`DESC`) order, with optional handling for null values (`NULLS FIRST` or `NULLS LAST`). Details: [ORDER BY Clause](../SQL-Manual/OrderBy-Clause_apache.md) - **OFFSET Clause**: Specifies the starting position for the query result, skipping the first `OFFSET` rows. Often used with the `LIMIT` clause. Details: [LIMIT and OFFSET Clause](../SQL-Manual/Limit-Offset-Clause.md) - **LIMIT Clause**: Limits the number of rows in the query result. Typically used in conjunction with the `OFFSET` clause for pagination. Details: [LIMIT and OFFSET Clause](../SQL-Manual/Limit-Offset-Clause.md) diff --git a/src/UserGuide/Master/Table/SQL-Manual/Fill-Clause.md b/src/UserGuide/Master/Table/SQL-Manual/Fill-Clause_apache.md similarity index 53% rename from src/UserGuide/Master/Table/SQL-Manual/Fill-Clause.md rename to src/UserGuide/Master/Table/SQL-Manual/Fill-Clause_apache.md index ed6c776bb..d644edaff 100644 --- a/src/UserGuide/Master/Table/SQL-Manual/Fill-Clause.md +++ b/src/UserGuide/Master/Table/SQL-Manual/Fill-Clause_apache.md @@ -21,17 +21,14 @@ # FILL Clause - ## 1. Function Introduction During data queries, you may encounter scenarios where certain columns have missing data in some rows, resulting in NULL values in the result set. These NULL values can hinder data visualization and analysis. To address this, IoTDB provides the FILL clause to populate these NULL values. -- If the query includes an `ORDER BY` clause, the FILL clause is executed before `ORDER BY`. -- If a `GAPFILL` (e.g., `date_bin_gapfill` function) operation exists, the FILL clause is executed after `GAPFILL`. +When the query contains an `ORDER BY` clause, the FILL clause is executed before `ORDER BY`. If a `GAPFILL` (`date_bin_gapfill` function) operation exists, the FILL clause is executed after `GAPFILL`. ## 2. Syntax Overview - ```sql fillClause : FILL METHOD fillMethod @@ -40,6 +37,7 @@ fillClause fillMethod : LINEAR timeColumnClause? fillGroupClause? #linearFill | PREVIOUS timeBoundClause? timeColumnClause? fillGroupClause? #previousFill + | NEXT timeBoundClause? timeColumnClause? fillGroupClause? #nextFill | CONSTANT literalExpression #valueFill ; @@ -63,52 +61,52 @@ intervalField ; ``` -### 2.1 ### Filling Methods +### 2.1 Filling Methods -IoTDB supports the following three methods to fill NULL values: +IoTDB supports the following four methods to fill NULL values: -1. **PREVIOUS Fill:** Uses the most recent non-NULL value from the same column to fill NULL values. Starting from V2.0.8, only this method supports the OBJECT type. -2. **LINEAR Fill:** Applies linear interpolation using the nearest previous and next non-NULL values in the same column. -3. **CONSTANT Fill:** Fills NULL values with a specified constant. +1. **`PREVIOUS` Fill:** Uses the previous non-NULL value in the same column to fill NULL values. +2. **`NEXT` Fill:** Uses the next non-NULL value in the same column to fill NULL values. +3. **`LINEAR` Fill:** Applies linear interpolation using the previous and next non-NULL values in the same column. +4. **`CONSTANT` Fill:** Fills NULL values with a specified constant. Only one filling method can be specified, and it applies to all columns in the result set. - ### 2.2 Supported Data Types for Filling Methods -| Data Type | Previous | Linear | Constant | -| :-------- | :------- | :----- | :------- | -| boolean | √ | - | √ | -| int32 | √ | √ | √ | -| int64 | √ | √ | √ | -| float | √ | √ | √ | -| double | √ | √ | √ | -| text | √ | - | √ | -| string | √ | - | √ | -| blob | √ | - | √ | -| timestamp | √ | √ | √ | -| date | √ | √ | √ | +| Data Type | Previous | Next | Linear | Constant | +| :-------- | :------- | :--- | :----- | :------- | +| boolean | √ | √ | - | √ | +| int32 | √ | √ | √ | √ | +| int64 | √ | √ | √ | √ | +| float | √ | √ | √ | √ | +| double | √ | √ | √ | √ | +| text | √ | √ | - | √ | +| string | √ | √ | - | √ | +| blob | √ | √ | - | √ | +| timestamp | √ | √ | √ | √ | +| date | √ | √ | √ | √ | +| OBJECT | √ | √ | - | - | **Note:** Columns with data types not supporting the specified filling method will remain unchanged without errors. ## 3. Sample Dataset - -The [Example Data page](../Reference/Sample-Data.md)page provides SQL statements to construct table schemas and insert data. By downloading and executing these statements in the IoTDB CLI, you can import the data into IoTDB. This data can be used to test and run the example SQL queries included in this documentation, allowing you to reproduce the described results. +The [Example Data page](../Reference/Sample-Data.md) provides SQL statements to construct table schemas and insert data. By downloading and executing these statements in the IoTDB CLI, you can import the data into IoTDB. This data can be used to test and run the example SQL queries included in this documentation, allowing you to reproduce the described results. ### 3.1 PREVIOUS Fill -`PREVIOUS FILL` fills NULL values with the most recent non-NULL value in the same column. +For NULL values in the query result set, the previous non-NULL value of the same column is used for filling. #### 3.1.1 Parameters -- **TIME_BOUND (optional):** Defines a forward-looking time threshold. If the time difference between the current NULL value and the previous non-NULL value exceeds this threshold, the value will not be filled. By default, the system uses the first `TIMESTAMP` column in the query result to determine the threshold. - - Format: A time interval specified with integer values and units, e.g., `1d1h` (1 day and 1 hour). -- **TIME_COLUMN (optional):** Allows specifying the `TIMESTAMP` column used to determine the time threshold. The column is specified using its positional index (starting from 1) in the original table. +- **TIME_BOUND (optional):** A forward-looking time threshold. If the time difference between the current NULL value and the previous non-NULL value exceeds this threshold, the value will not be filled. By default, the system uses the first `TIMESTAMP` column in the query result to determine whether the threshold is exceeded. + - The time threshold is specified as a time interval. The numeric part must be an integer, and the unit part can be `y` (year), `mo` (month), `w` (week), `d` (day), `h` (hour), `m` (minute), `s` (second), `ms` (millisecond), `µs` (microsecond), or `ns` (nanosecond), e.g., `1d1h`. +- **TIME_COLUMN (optional):** Allows manually specifying the `TIMESTAMP` column used to determine the time threshold. The column is specified by appending a number (starting from 1) after the `TIME_COLUMN` parameter, which represents the positional index of the `TIMESTAMP` column in the original table. #### 3.1.2 Examples -- Without FILL Clause: +Without any filling method: ```sql SELECT time, temperature, status @@ -135,7 +133,7 @@ Total line number = 7 It costs 0.088s ``` -- Using `PREVIOUS Fill`: +Using the `PREVIOUS` fill method (NULL values will be filled with the previous non-NULL value): ```sql SELECT time, temperature, status @@ -163,22 +161,22 @@ Total line number = 7 It costs 0.091s ``` -- Using `PREVIOUS Fill` with a Specified Time Threshold: +Using the `PREVIOUS` fill method (with a specified time threshold): ```sql -# Do not specify a time column +-- Do not specify a time column SELECT time, temperature, status FROM table1 WHERE time >= 2024-11-27 00:00:00 and time <= 2024-11-29 00:00:00 AND plant_id='1001' and device_id='101' FILL METHOD PREVIOUS TIME_BOUND 1m; -# Manually specify the time column +-- Manually specify the time column SELECT time, temperature, status FROM table1 WHERE time >= 2024-11-27 00:00:00 and time <= 2024-11-29 00:00:00 AND plant_id='1001' and device_id='101' - FILL METHOD PREVIOUS 1m TIME_COLUMN 1; + FILL METHOD PREVIOUS TIME_BOUND 1m TIME_COLUMN 1; ``` Results: @@ -199,24 +197,132 @@ Total line number = 7 It costs 0.075s ``` -### 3.2 LINEAR Fill +### 3.2 NEXT Fill + +For NULL values in the query result set, the next non-NULL value of the same column is used for filling. (Supported since V2.0.11) + +#### 3.2.1 Parameters + +- **TIME_BOUND (optional):** A backward-looking time threshold. If the time difference between the current NULL value and the next non-NULL value exceeds this threshold, the value will not be filled. If this parameter is specified, the system automatically selects the first column in the `SELECT` clause whose return type is `TIMESTAMP` as the time column for threshold checking. +- **FILL_GROUP (optional):** Specifies grouping columns; filling only occurs within the same group. If this parameter is specified, the system automatically selects the first column in the `SELECT` clause whose return type is `TIMESTAMP` as the time column for sorting within each group. +- **TIME_COLUMN (optional):** Allows manually specifying the `TIMESTAMP` column used to determine the time threshold. The column is specified by appending a number (starting from 1) after the `TIME_COLUMN` parameter, which represents the positional index of the column in the `SELECT` list. + +**Notes:** + +- If neither `TIME_BOUND` nor `FILL_GROUP` is specified but `TIME_COLUMN` is specified, a syntax error will be thrown. +- If `TIME_BOUND` or `FILL_GROUP` is specified but `TIME_COLUMN` is not, and no `TIMESTAMP`-type column exists in the `SELECT` clause, an exception will be thrown. +- If the specified `TIME_COLUMN` column is not of `TIMESTAMP` type, or the specified position is out of the range of the `SELECT` list, an exception will be thrown. + +#### 3.2.2 Examples + +Without any filling method: + +```sql +SELECT time, temperature, status + FROM table1 + WHERE time >= 2024-11-27 00:00:00 and time <= 2024-11-29 00:00:00 + AND plant_id='1001' and device_id='101'; +``` + +Results: + +```sql ++-----------------------------+-----------+------+ +| time|temperature|status| ++-----------------------------+-----------+------+ +|2024-11-27T16:38:00.000+08:00| null| true| +|2024-11-27T16:39:00.000+08:00| 85.0| null| +|2024-11-27T16:40:00.000+08:00| 85.0| null| +|2024-11-27T16:41:00.000+08:00| 85.0| null| +|2024-11-27T16:42:00.000+08:00| null| false| +|2024-11-27T16:43:00.000+08:00| null| false| +|2024-11-27T16:44:00.000+08:00| null| false| ++-----------------------------+-----------+------+ +Total line number = 7 +It costs 0.061s +``` + +Using the `NEXT` fill method (NULL values will be filled with the next non-NULL value): + +```sql +SELECT time, temperature, status + FROM table1 + WHERE time >= 2024-11-27 00:00:00 and time <= 2024-11-29 00:00:00 + AND plant_id='1001' and device_id='101' + FILL METHOD NEXT; +``` + +Results: + +```sql ++-----------------------------+-----------+------+ +| time|temperature|status| ++-----------------------------+-----------+------+ +|2024-11-27T16:38:00.000+08:00| 85.0| true| +|2024-11-27T16:39:00.000+08:00| 85.0| false| +|2024-11-27T16:40:00.000+08:00| 85.0| false| +|2024-11-27T16:41:00.000+08:00| 85.0| false| +|2024-11-27T16:42:00.000+08:00| null| false| +|2024-11-27T16:43:00.000+08:00| null| false| +|2024-11-27T16:44:00.000+08:00| null| false| ++-----------------------------+-----------+------+ +Total line number = 7 +It costs 0.033s +``` + +Using the `NEXT` fill method (with a specified time threshold): + +```sql +-- Do not specify a time column +SELECT time, temperature, status + FROM table1 + WHERE time >= 2024-11-27 00:00:00 and time <= 2024-11-29 00:00:00 + AND plant_id='1001' and device_id='101' + FILL METHOD NEXT TIME_BOUND 1m; + +-- Manually specify the time column +SELECT time, temperature, status + FROM table1 + WHERE time >= 2024-11-27 00:00:00 and time <= 2024-11-29 00:00:00 + AND plant_id='1001' and device_id='101' + FILL METHOD NEXT TIME_BOUND 1m TIME_COLUMN 1; +``` + +Results: + +```sql ++-----------------------------+-----------+------+ +| time|temperature|status| ++-----------------------------+-----------+------+ +|2024-11-27T16:38:00.000+08:00| 85.0| true| +|2024-11-27T16:39:00.000+08:00| 85.0| null| +|2024-11-27T16:40:00.000+08:00| 85.0| null| +|2024-11-27T16:41:00.000+08:00| 85.0| false| +|2024-11-27T16:42:00.000+08:00| null| false| +|2024-11-27T16:43:00.000+08:00| null| false| +|2024-11-27T16:44:00.000+08:00| null| false| ++-----------------------------+-----------+------+ +Total line number = 7 +It costs 0.047s +``` -`LINEAR Fill` fills NULL values using linear interpolation based on the nearest previous and next non-NULL values in the same column. +### 3.3 LINEAR Fill -#### 3.2.1 Linear Fill Rules +For NULL values in the query result set, linear interpolation based on the previous and next non-NULL values of the same column is used for filling. -1. If all previous or all subsequent values are NULL, no filling is performed. -2. Columns with data types such as `boolean`, `string`, `blob`, or `text` are not filled, and no error is returned. -3. If no auxiliary time column is specified, the first `TIMESTAMP`-type column in the `SELECT` clause is used by default for interpolation. If no `TIMESTAMP` column exists, an error will be returned. +#### 3.3.1 Linear Fill Rules -#### 3.2.2 Parameters +- If all previous values or all subsequent values are NULL, no filling is performed. +- Columns with data types such as `boolean`, `string`, `blob`, or `text` are not filled, and no error is returned. +- If no time column is specified, the first `TIMESTAMP`-type column in the `SELECT` clause is used by default as the auxiliary time column for linear interpolation. If no `TIMESTAMP`-type column exists, an exception will be thrown. -- **TIME_COLUMN (optional):** Specifies the `TIMESTAMP` column to be used as an auxiliary column for linear interpolation. The column is identified by its positional index (starting from 1) in the original table. +#### 3.3.2 Parameters -**Note:** The auxiliary column used for linear interpolation is not required to be the `time` column. However, the auxiliary column must be sorted in ascending or descending order for meaningful interpolation. If another column is specified, the user must ensure the result set is ordered correctly. +- **TIME_COLUMN (optional):** Allows manually specifying the `TIMESTAMP` column used as the auxiliary column for linear interpolation. The column is specified by appending a number (starting from 1) after the `TIME_COLUMN` parameter, which represents the positional index of the `TIMESTAMP` column in the original table. -#### 3.2.3 Examples +**Note:** The auxiliary column used for linear interpolation is not required to be the `time` column. Any expression of `TIMESTAMP` type can be used. However, since linear interpolation is only meaningful when the auxiliary column is sorted in ascending or descending order, if another column is specified, the user must ensure the result set is ordered by that column in ascending or descending order. +#### 3.3.3 Examples ```sql SELECT time, temperature, status @@ -226,7 +332,7 @@ SELECT time, temperature, status FILL METHOD LINEAR; ``` -Result: +Results: ```sql +-----------------------------+-----------+------+ @@ -244,20 +350,18 @@ Total line number = 7 It costs 0.053s ``` -### 3.3 ### CONSTANT Fill +### 3.4 CONSTANT Fill -`CONSTANT Fill` fills NULL values with a specified constant value. +For NULL values in the query result set, a specified constant is used for filling. -#### 3.3.1 Constant Fill Rules +#### 3.4.1 Constant Fill Rules -1. If the data type of the constant does not match the column's data type, IoTDB does not fill the result set and no error is returned. -2. If the constant value exceeds the column's allowable range, IoTDB does not fill the result set and no error is returned. +- If the data type of the constant does not match the column's data type, IoTDB does not fill the query result, and no error is returned. +- If the constant value exceeds the maximum value that the data type can represent, IoTDB does not fill the query result, and no error is returned. +#### 3.4.2 Examples -#### 3.3.2 Examples - -- Using a `FLOAT` constant: - +Using a `FLOAT` constant: ```sql SELECT time, temperature, status @@ -285,7 +389,7 @@ Total line number = 7 It costs 0.242s ``` -W- Using a `BOOLEAN` constant: +Using a `BOOLEAN` constant: ```sql SELECT time, temperature, status @@ -315,13 +419,12 @@ It costs 0.073s ## 4. Advanced Usage -When using the `PREVIOUS` or `LINEAR` FILL methods, the `FILL_GROUP` parameter allows filling within specific groups without being influenced by other groups. +When using `PREVIOUS`, `NEXT`, or `LINEAR` FILL, an additional `FILL_GROUP` parameter is supported to perform filling within groups. -#### Examples +When using the GROUP BY clause together with FILL, you may want to fill NULL values within each group without being affected by other groups. -- **Filling Missing Values Within `device_id`** +For example, fill the NULL values within each `device_id` group without using values from other devices: -The following query demonstrates how to fill missing values for each `device_id` group independently, without using values from other devices: ```sql SELECT date_bin(1h, time) AS hour_time, plant_id, device_id, avg(temperature) AS avg_temp FROM table1 @@ -329,7 +432,7 @@ SELECT date_bin(1h, time) AS hour_time, plant_id, device_id, avg(temperature) A group by 1, plant_id, device_id; ``` -Results: +Results: ```sql +-----------------------------+--------+---------+--------+ @@ -348,9 +451,7 @@ Total line number = 8 It costs 0.110s ``` -- **Without Specifying `FILL_GROUP`** - -If the `FILL_GROUP` parameter is not specified, missing values in `device_id = 100` will be filled using values from `device_id = 101`: +If the `FILL_GROUP` parameter is not specified, the NULL values of `100` will be filled with the values of `101`: ```sql SELECT date_bin(1h, time) AS hour_time, plant_id, device_id, avg(temperature) AS avg_temp @@ -360,7 +461,7 @@ SELECT date_bin(1h, time) AS hour_time, plant_id, device_id, avg(temperature) A FILL METHOD PREVIOUS; ``` -Results: +Results: ```sql +-----------------------------+--------+---------+--------+ @@ -379,9 +480,7 @@ Total line number = 8 It costs 0.066s ``` -- **Specifying `FILL_GROUP` for Grouped Filling** - -By specifying `FILL_GROUP 2`, the filling is restricted to groups based on the second column (`device_id`). As a result, missing values in `device_id = 100` will not be filled using values from `device_id = 101`: +After specifying `FILL_GROUP` as the 2nd column, filling only occurs within groups keyed by the second column `device_id`. The NULL values of `100` will not be filled with the values of `101`, because they belong to different groups. ```sql SELECT date_bin(1h, time) AS hour_time, plant_id, device_id, avg(temperature) AS avg_temp @@ -412,16 +511,12 @@ It costs 0.089s ## 5. Special Notes -When using `LINEAR` or `PREVIOUS` FILL methods, if the auxiliary time column (used to determine filling logic) contains NULL values, IoTDB follows these rules: +When using `LINEAR FILL`, `PREVIOUS FILL`, or `NEXT FILL`, if the auxiliary time column (the time column used to determine the filling logic) contains NULL values, IoTDB follows these rules: -- Rows with NULL values in the auxiliary column will not be filled. +- Rows whose auxiliary time column is NULL will not be filled. - These rows are also excluded from the filling logic calculations. -**Example of `PREVIOUS Fill`** - -- Query original data: - - +Taking `PREVIOUS FILL` as an example, the original data is as follows: ```sql SELECT time, plant_id, device_id, humidity, arrival_time @@ -448,7 +543,7 @@ Total line number = 7 It costs 0.119s ``` -- Using `arrival_time` as the auxiliary column with a time interval (`TIME_BOUND`) of 2 seconds +Using the `arrival_time` column as the auxiliary time column, with a time interval (`TIME_BOUND`) of 2 seconds (values are not filled if the previous non-NULL value is more than 2 seconds away from the current value): ```sql SELECT time, plant_id, device_id, humidity, arrival_time @@ -475,15 +570,9 @@ Results: Total line number = 7 It costs 0.049s ``` -**Filling Details** - -1. For `humidity` at `16:39`, `16:42`, and `16:43`: - 1. Since the auxiliary column `arrival_time` is NULL, no filling is performed. -2. For `humidity` at `16:40`: - 1. The auxiliary column `arrival_time` is not NULL and has a value of `1970-01-01T08:00:00.003+08:00`. - 2. The time difference from the previous non-NULL value (`1970-01-01T08:00:00.001+08:00`) is less than 2 seconds (`TIME_BOUND`) - 3. So the value `35.1` from the first row is used for filling. -3. For `humidity` at `16:41`: - 1. Although the auxiliary column `arrival_time` is not NULL, the time difference from the previous non-NULL value exceeds 2 seconds, so no filling is performed. -4. For `humidity` at `16:44`: - 1. Similarly, the time difference exceeds 2 seconds, so no filling is performed. \ No newline at end of file + +Filling details: + +- For the `humidity` column at 16:39, 16:42, and 16:43: since the auxiliary column `arrival_time` is NULL, no filling is performed. +- For the `humidity` column at 16:40: the auxiliary column `arrival_time` is not NULL (`1970-01-01T08:00:00.003+08:00`), and the time difference from the previous non-NULL value (`1970-01-01T08:00:00.001+08:00`) does not exceed 2 seconds, so the value `35.1` of the first row is used for filling. +- For the `humidity` column at 16:41: although `arrival_time` is not NULL, the time difference from the previous non-NULL value exceeds 2 seconds, so no filling is performed. The same applies to the seventh row. diff --git a/src/UserGuide/latest-Table/SQL-Manual/GroupBy-Clause.md b/src/UserGuide/Master/Table/SQL-Manual/GroupBy-Clause_apache.md similarity index 56% rename from src/UserGuide/latest-Table/SQL-Manual/GroupBy-Clause.md rename to src/UserGuide/Master/Table/SQL-Manual/GroupBy-Clause_apache.md index 253009fcb..cb4324fb3 100644 --- a/src/UserGuide/latest-Table/SQL-Manual/GroupBy-Clause.md +++ b/src/UserGuide/Master/Table/SQL-Manual/GroupBy-Clause_apache.md @@ -27,26 +27,24 @@ GROUP BY expression (',' expression)* ``` -- The `GROUP BY` clause is used to group the result set of a `SELECT` statement based on the specified column values. The values of the grouping columns remain unchanged in the results, while other columns with the same grouping column values are calculated using specified aggregate functions (e.g., `COUNT`, `AVG`). +- The GROUP BY clause is used to group the result set of a SELECT statement by the values of the specified columns for aggregated computation. The values of these grouping columns are kept as-is in the result, while all other records that share the same grouping column values are computed through the specified aggregate functions (e.g., COUNT, AVG). ![](/img/groupby01.png) ## 2. Notes -#### 2.1 Items in the `SELECT` Clause +- Items in the SELECT clause must either contain aggregate functions or consist of columns that appear in the GROUP BY clause. -Items in the `SELECT` clause must either include aggregate functions or consist of columns specified in the `GROUP BY` clause. - -Valid Example: +Valid example: ```sql SELECT concat(device_id, model_id), avg(temperature) FROM table1 - GROUP BY device_id, model_id; -- valid + GROUP BY device_id, model_id; ``` -Result: +Results: ```sql +-----+-----+ @@ -63,48 +61,46 @@ Total line number = 6 It costs 0.094s ``` -Invalid Example 1: +Invalid example 1: ```sql SELECT device_id, temperature FROM table1 - GROUP BY device_id;-- invalid + GROUP BY device_id; ``` -Error Message: +Results: ```sql Msg: org.apache.iotdb.jdbc.IoTDBSQLException: 701: 'temperature' must be an aggregate expression or appear in GROUP BY clause ``` -Invalid Example 2: +Invalid example 2: ```sql SELECT device_id, avg(temperature) FROM table1 - GROUP BY model; -- invalid + GROUP BY model; ``` -Error Message: +Results: ```sql Msg: org.apache.iotdb.jdbc.IoTDBSQLException: 701: Column 'model' cannot be resolved ``` -#### 2.2 Without a `GROUP BY` Clause +- If there is no GROUP BY clause, all items in the SELECT clause must either contain aggregate functions or contain no aggregate functions at all. -If there is no `GROUP BY` clause, all items in the `SELECT` clause must either include aggregate functions or exclude them entirely. - -Valid Example: +Valid example: ```sql SELECT COUNT(*), avg(temperature) - FROM table1; -- valid + FROM table1; ``` -Result: +Results: ```sql +-----+-----------------+ @@ -116,24 +112,20 @@ Total line number = 1 It costs 0.094s ``` -Invalid Example: +Invalid example: ```sql -SELECT humidity, avg(temperature) FROM table1; -- invalid +SELECT humidity, avg(temperature) FROM table1; ``` -Result: +Results: ```sql Msg: org.apache.iotdb.jdbc.IoTDBSQLException: 701: 'humidity' must be an aggregate expression or appear in GROUP BY clause ``` -#### 2.3 Using Constant Integers in `GROUP BY` Clause - -The `GROUP BY` clause supports referencing `SELECT` items using constant integers starting from 1. If the constant is less than 1 or exceeds the size of the `SELECT` item list, an error will occur. - -Example: +- The GROUP BY clause can use constant integers starting from 1 to reference items in the SELECT clause. If the constant integer is less than 1 or greater than the size of the select item list, an error will be thrown. ```sql SELECT date_bin(1h, time), device_id, avg(temperature) @@ -142,7 +134,7 @@ SELECT date_bin(1h, time), device_id, avg(temperature) GROUP BY 1, device_id; ``` -Result: +Results: ```sql +-----------------------------+---------+-----+ @@ -158,11 +150,7 @@ Total line number = 5 It costs 0.092s ``` -#### 2.4 Alias Restrictions in `GROUP BY` Clause - -Aliases from `SELECT` items cannot be used in the `GROUP BY` clause. Use the original expression instead. - -Example: +- In versions prior to V2.0.11, using the alias of a select item in the GROUP BY clause was not supported. You needed to use the complete expression (or the constant index of the select item) instead, as shown in the following SQL: ```sql SELECT date_bin(1h, time) AS hour_time, device_id, avg(temperature) @@ -171,7 +159,7 @@ SELECT date_bin(1h, time) AS hour_time, device_id, avg(temperature) GROUP BY date_bin(1h, time), device_id; ``` -Result: +Results: ```sql +-----------------------------+---------+-----+ @@ -187,17 +175,71 @@ Total line number = 5 It costs 0.092s ``` -#### 2.5 Using Aggregate Functions with `\*` +- Since V2.0.11, the GROUP BY clause supports referencing aliases explicitly defined in the SELECT clause. + - This capability only applies when directly referencing the alias itself; names with table name prefixes (e.g., `GROUP BY table1.hour_time`) are not expanded as SELECT aliases and are still resolved as regular expressions. + - A name referenced in GROUP BY is first resolved as an input column of the current query; only when it cannot be resolved as an input column will it be further resolved as a SELECT alias. If multiple aliases with the same name exist in the SELECT list, an ambiguity error will be thrown when referencing that alias. + - After alias resolution in GROUP BY, the existing GROUP BY validation rules still apply. For example, grouping keys cannot contain aggregate functions, window functions, or grouping functions. + +Valid example: + +```sql +SELECT date_bin(1h, time) AS hour_time, device_id, avg(temperature) + FROM table1 + WHERE time >= 2024-11-27 00:00:00 and time <= 2024-11-29 00:00:00 + GROUP BY hour_time, device_id; +``` + +Results: -Only the `COUNT` function can be used with `*` to calculate the total number of rows. Using `*` with other aggregate functions will result in an error. +```sql ++-----------------------------+---------+-----+ +| hour_time|device_id|_col2| ++-----------------------------+---------+-----+ +|2024-11-28T08:00:00.000+08:00| 100| 85.0| +|2024-11-28T09:00:00.000+08:00| 100| null| +|2024-11-28T10:00:00.000+08:00| 100| 85.0| +|2024-11-28T11:00:00.000+08:00| 100| 88.0| +|2024-11-27T16:00:00.000+08:00| 101| 85.0| ++-----------------------------+---------+-----+ +Total line number = 5 +It costs 0.228s +``` -Example: +Invalid example 1: multiple aliases with the same name in one statement + +```sql +SELECT temperature AS value, humidity AS value + FROM table1 + GROUP BY value; +``` + +Results: + +```sql +Msg: org.apache.iotdb.jdbc.IoTDBSQLException: 701: Column alias 'value' is ambiguous at positions 1, 2 +``` + +Invalid example 2: grouping keys containing aggregate functions + +```sql +SELECT AVG(temperature) AS avg_temperature + FROM table1 + GROUP BY avg_temperature; +``` + +Results: + +```sql +Msg: org.apache.iotdb.jdbc.IoTDBSQLException: 701: GROUP BY clause cannot contain aggregations, window functions or grouping operations: [AVG(temperature)] +``` + +- Only the COUNT function can be used with an asterisk (`*`) to count the total number of rows in a table. Using other aggregate functions with `*` will throw an error. ```sql SELECT count(*) FROM table1; ``` -Result: +Results: ```sql +-----+ @@ -209,13 +251,13 @@ Total line number = 1 It costs 0.047s ``` -## 3. Sample Data and Usage Examples +## 3. Sample Dataset -The [Example Data page](../Reference/Sample-Data.md)page provides SQL statements to construct table schemas and insert data. By downloading and executing these statements in the IoTDB CLI, you can import the data into IoTDB. This data can be used to test and run the example SQL queries included in this documentation, allowing you to reproduce the described results. +The [Example Data page](../Reference/Sample-Data.md) provides SQL statements to construct table schemas and insert data. By downloading and executing these statements in the IoTDB CLI, you can import the data into IoTDB. This data can be used to test and run the example SQL queries included in this documentation, allowing you to reproduce the described results. -#### Example 1: Downsampling Time-Series Data +#### Example 1: Downsampling Time Series Data -Downsample the temperature of device `101` over the specified time range, returning one average temperature per hour: +Downsample the temperature of device 101 over the following time range, returning an average temperature per hour. ```sql SELECT date_bin(1h, time) AS hour_time, AVG(temperature) AS avg_temperature @@ -225,7 +267,17 @@ SELECT date_bin(1h, time) AS hour_time, AVG(temperature) AS avg_temperature GROUP BY 1; ``` -Result: +Since V2.0.11, GROUP BY items can directly reference aliases explicitly defined in the SELECT clause, so the SQL above can be written as: + +```sql +SELECT date_bin(1h, time) AS hour_time, AVG(temperature) AS avg_temperature + FROM table1 + WHERE time >= 2024-11-27 00:00:00 and time <= 2024-11-30 00:00:00 + AND device_id='101' + GROUP BY hour_time; +``` + +Results: ```sql +-----------------------------+---------------+ @@ -238,7 +290,7 @@ Total line number = 2 It costs 0.054s ``` -Downsample the temperature of all devices over the past day, returning one average temperature per hour for each device: +Downsample the temperature of each device over the past day, returning an average temperature per hour. ```sql SELECT date_bin(1h, time) AS hour_time, device_id, AVG(temperature) AS avg_temperature @@ -247,7 +299,7 @@ SELECT date_bin(1h, time) AS hour_time, device_id, AVG(temperature) AS avg_tempe GROUP BY 1, device_id; ``` -Result: +Results: ```sql +-----------------------------+---------+---------------+ @@ -266,10 +318,9 @@ Total line number = 8 It costs 0.081s ``` - For more details on the `date_bin` function, refer to the **[Definition of Date Bin (Time Bucketing)](../SQL-Manual/Featured-Functions.md#_1-1-date-bin-function)** feature documentation. -#### Example 2: Query the Latest Data Point for Each Device +#### Example 2: Querying the Latest Data Point of Each Device ```sql SELECT device_id, LAST(temperature), LAST_BY(time, temperature) @@ -277,7 +328,7 @@ SELECT device_id, LAST(temperature), LAST_BY(time, temperature) GROUP BY device_id; ``` -Result: +Results: ```sql +---------+-----+-----------------------------+ @@ -290,15 +341,15 @@ Total line number = 2 It costs 0.078s ``` -#### Example 3: Count Total Rows +#### Example 3: Counting Total Rows -Count the total number of rows for all devices: +Count the total number of rows of all devices: ```sql SELECT COUNT(*) FROM table1; ``` -Result: +Results: ```sql +-----+ @@ -310,7 +361,7 @@ Total line number = 1 It costs 0.060s ``` -Count the total number of rows for each device: +Count the total number of rows of each device: ```sql SELECT device_id, COUNT(*) AS total_rows @@ -318,7 +369,7 @@ SELECT device_id, COUNT(*) AS total_rows GROUP BY device_id; ``` -Result: +Results: ```sql +---------+----------+ @@ -331,7 +382,7 @@ Total line number = 2 It costs 0.060s ``` -#### Example 4: Aggregate without a `GROUP BY` Clause +#### Example 4: Aggregation Without a GROUP BY Clause Query the maximum temperature across all devices: @@ -340,7 +391,7 @@ SELECT MAX(temperature) FROM table1; ``` -Result: +Results: ```sql +-----+ @@ -352,9 +403,9 @@ Total line number = 1 It costs 0.086s ``` -#### Example 5: Aggregate Results from a Subquery +#### Example 5: Aggregating the Results of a Subquery -Query the combinations of plants and devices where the average temperature exceeds 80.0 over a specified time range and has at least two records: +Query the plant and device combinations whose average temperature exceeds 80.0 with at least two records during the specified time period: ```sql SELECT plant_id, device_id @@ -367,7 +418,7 @@ GROUP BY plant_id, device_id HAVING COUNT(*) > 1; ``` -Result: +Results: ```sql +--------+---------+ @@ -378,4 +429,4 @@ Result: +--------+---------+ Total line number = 2 It costs 0.073s -``` \ No newline at end of file +``` diff --git a/src/UserGuide/Master/Table/SQL-Manual/OrderBy-Clause.md b/src/UserGuide/Master/Table/SQL-Manual/OrderBy-Clause_apache.md similarity index 74% rename from src/UserGuide/Master/Table/SQL-Manual/OrderBy-Clause.md rename to src/UserGuide/Master/Table/SQL-Manual/OrderBy-Clause_apache.md index a9348f990..829ad24fe 100644 --- a/src/UserGuide/Master/Table/SQL-Manual/OrderBy-Clause.md +++ b/src/UserGuide/Master/Table/SQL-Manual/OrderBy-Clause_apache.md @@ -19,9 +19,7 @@ --> -# ORDER BY Clauses - -The `ORDER BY` clause is used to sort the result set of a query at its final stage based on specified sorting conditions. +# ORDER BY Clause ## 1. Syntax Overview @@ -33,19 +31,19 @@ sortItem ; ``` -### 1.1 ORDER BY Clauses - -- Allows sorting query result rows based on specified conditions in ascending order (`ASC`) or descending order (`DESC`). -- Provides control over the position of `NULL` values, enabling users to specify whether `NULL` values appear at the beginning (`NULLS FIRST`) or the end (`NULLS LAST`). -- By default, sorting is applied as `ASC NULLS LAST`, meaning values are sorted in ascending order and `NULL` values are placed at the end. Users can manually specify other parameters to override the default behavior. -- The `ORDER BY` clause is executed before the `LIMIT` or `OFFSET` clauses. +### 1.1 ORDER BY Clause -## 2. Example Data +- Used to sort the result set at the final stage of a query. Based on the specified sorting conditions, the rows in the query result can be arranged in ascending (ASC) or descending (DESC) order. +- Provides control over the sorting position of NULL values, allowing users to specify whether NULL values are placed at the beginning (NULLS FIRST) or the end (NULLS LAST) of the result. +- By default, `ASC NULLS LAST` is used, i.e., values are sorted in ascending order with NULL values placed last. The default sorting order can be changed by manually specifying other parameters. +- The ORDER BY clause is executed before the LIMIT or OFFSET clause. +- Since V2.0.11, the ORDER BY clause supports referencing aliases explicitly defined in the SELECT clause. When a name is directly referenced in ORDER BY, it is first resolved as a SELECT output alias; if multiple aliases with the same name exist in the SELECT list, an ambiguity error will be thrown when referencing that alias. +## 2. Sample Dataset -The [Example Data page](../Reference/Sample-Data.md)page provides SQL statements to construct table schemas and insert data. By downloading and executing these statements in the IoTDB CLI, you can import the data into IoTDB. This data can be used to test and run the example SQL queries included in this documentation, allowing you to reproduce the described results. +The [Example Data page](../Reference/Sample-Data.md) provides SQL statements to construct table schemas and insert data. By downloading and executing these statements in the IoTDB CLI, you can import the data into IoTDB. This data can be used to test and run the example SQL queries included in this documentation, allowing you to reproduce the described results. -#### Example 1: Query data from the past hour in descending order of time +#### Example 1: Query Data of the Past Hour Sorted by Time in Descending Order ```sql SELECT * @@ -76,7 +74,7 @@ Total line number = 11 It costs 0.148s ``` -#### Example 2: Query data sorted by device_id in ascending order and time in descending order, with NULL temperatures displayed first +#### Example 2: Query Data of All Devices Sorted by device_id in Ascending Order and Time in Descending Order, with NULL temperature Displayed First ```sql SELECT * @@ -107,7 +105,7 @@ Total line number = 11 It costs 0.060s ``` -#### Example 3: Query the top 10 rows with the highest temperature values +#### Example 3: Query the Top 10 Rows with the Highest Temperature ```sql SELECT * @@ -135,4 +133,33 @@ Results: +-----------------------------+------+--------+---------+--------+-----------+-----------+--------+------+-----------------------------+ Total line number = 10 It costs 0.069s -``` \ No newline at end of file +``` + +#### Example 4: Aggregate by Time Bucket and Sort by Alias (via SELECT Alias) + +```sql +SELECT date_bin(1h, time) AS hour_time, AVG(temperature) AS avg_temperature + FROM table1 + WHERE time >= 2024-11-27 00:00:00 and time <= 2024-11-30 00:00:00 + GROUP BY hour_time + ORDER BY hour_time; +``` + +Results: + +```sql ++-----------------------------+---------------+ +| hour_time|avg_temperature| ++-----------------------------+---------------+ +|2024-11-27T16:00:00.000+08:00| 85.0| +|2024-11-28T08:00:00.000+08:00| 85.0| +|2024-11-28T09:00:00.000+08:00| null| +|2024-11-28T10:00:00.000+08:00| 85.0| +|2024-11-28T11:00:00.000+08:00| 88.0| +|2024-11-29T10:00:00.000+08:00| 85.0| +|2024-11-29T11:00:00.000+08:00| null| +|2024-11-29T18:00:00.000+08:00| 90.0| ++-----------------------------+---------------+ +Total line number = 8 +It costs 0.079s +``` diff --git a/src/UserGuide/Master/Table/SQL-Manual/Select-Clause_apache.md b/src/UserGuide/Master/Table/SQL-Manual/Select-Clause_apache.md index 3c70e6776..c7e4b12df 100644 --- a/src/UserGuide/Master/Table/SQL-Manual/Select-Clause_apache.md +++ b/src/UserGuide/Master/Table/SQL-Manual/Select-Clause_apache.md @@ -119,7 +119,7 @@ It costs 0.653s #### 3.1.2 Aggregate Functions -Aggregate functions summarize multiple rows into a single value. When aggregate functions are present in the `SELECT` clause, the query is treated as an **aggregate query**. All expressions in the query must either be part of an aggregate function or specified in the [GROUP BY clause](../SQL-Manual/GroupBy-Clause.md). +Aggregate functions summarize multiple rows into a single value. When aggregate functions are present in the `SELECT` clause, the query is treated as an **aggregate query**. All expressions in the query must either be part of an aggregate function or specified in the [GROUP BY clause](../SQL-Manual/GroupBy-Clause_apache.md). **Example 1**: Total number of rows in a table. diff --git a/src/UserGuide/Master/Table/SQL-Manual/overview_apache.md b/src/UserGuide/Master/Table/SQL-Manual/overview_apache.md index e6b98ca16..548e16ffa 100644 --- a/src/UserGuide/Master/Table/SQL-Manual/overview_apache.md +++ b/src/UserGuide/Master/Table/SQL-Manual/overview_apache.md @@ -40,10 +40,10 @@ The IoTDB table model query syntax supports the following clauses: - **SELECT Clause**: Specifies the columns to be included in the result. Details: [SELECT Clause](../SQL-Manual/Select-Clause_apache.md) - **FROM Clause**: Indicates the data source for the query, which can be a single table, multiple tables joined using the `JOIN` clause, or a subquery. Details: [FROM & JOIN Clause](../SQL-Manual/From-Join-Clause.md) - **WHERE Clause**: Filters rows based on specific conditions. Logically executed immediately after the `FROM` clause. Details: [WHERE Clause](../SQL-Manual/Where-Clause.md) -- **GROUP BY Clause**: Used for aggregating data, specifying the columns for grouping. Details: [GROUP BY Clause](../SQL-Manual/GroupBy-Clause.md) +- **GROUP BY Clause**: Used for aggregating data, specifying the columns for grouping. Details: [GROUP BY Clause](../SQL-Manual/GroupBy-Clause_apache.md) - **HAVING Clause**: Applied after the `GROUP BY` clause to filter grouped data, similar to `WHERE` but operates after grouping. Details:[HAVING Clause](../SQL-Manual/Having-Clause.md) -- **FILL Clause**: Handles missing values in query results by specifying fill methods (e.g., previous non-null value or linear interpolation) for better visualization and analysis. Details:[FILL Clause](../SQL-Manual/Fill-Clause.md) -- **ORDER BY Clause**: Sorts query results in ascending (`ASC`) or descending (`DESC`) order, with optional handling for null values (`NULLS FIRST` or `NULLS LAST`). Details: [ORDER BY Clause](../SQL-Manual/OrderBy-Clause.md) +- **FILL Clause**: Handles missing values in query results by specifying fill methods (e.g., previous non-null value or linear interpolation) for better visualization and analysis. Details:[FILL Clause](../SQL-Manual/Fill-Clause_apache.md) +- **ORDER BY Clause**: Sorts query results in ascending (`ASC`) or descending (`DESC`) order, with optional handling for null values (`NULLS FIRST` or `NULLS LAST`). Details: [ORDER BY Clause](../SQL-Manual/OrderBy-Clause_apache.md) - **OFFSET Clause**: Specifies the starting position for the query result, skipping the first `OFFSET` rows. Often used with the `LIMIT` clause. Details: [LIMIT and OFFSET Clause](../SQL-Manual/Limit-Offset-Clause.md) - **LIMIT Clause**: Limits the number of rows in the query result. Typically used in conjunction with the `OFFSET` clause for pagination. Details: [LIMIT and OFFSET Clause](../SQL-Manual/Limit-Offset-Clause.md) diff --git a/src/UserGuide/latest-Table/Basic-Concept/Query-Data_apache.md b/src/UserGuide/latest-Table/Basic-Concept/Query-Data_apache.md index 3f45018e6..8115e37d1 100644 --- a/src/UserGuide/latest-Table/Basic-Concept/Query-Data_apache.md +++ b/src/UserGuide/latest-Table/Basic-Concept/Query-Data_apache.md @@ -40,10 +40,10 @@ The IoTDB table model query syntax supports the following clauses: - **SELECT Clause**: Specifies the columns to be included in the result. Details: [SELECT Clause](../SQL-Manual/Select-Clause_apache.md) - **FROM Clause**: Indicates the data source for the query, which can be a single table, multiple tables joined using the `JOIN` clause, or a subquery. Details: [FROM & JOIN Clause](../SQL-Manual/From-Join-Clause.md) - **WHERE Clause**: Filters rows based on specific conditions. Logically executed immediately after the `FROM` clause. Details: [WHERE Clause](../SQL-Manual/Where-Clause.md) -- **GROUP BY Clause**: Used for aggregating data, specifying the columns for grouping. Details: [GROUP BY Clause](../SQL-Manual/GroupBy-Clause.md) +- **GROUP BY Clause**: Used for aggregating data, specifying the columns for grouping. Details: [GROUP BY Clause](../SQL-Manual/GroupBy-Clause_apache.md) - **HAVING Clause**: Applied after the `GROUP BY` clause to filter grouped data, similar to `WHERE` but operates after grouping. Details:[HAVING Clause](../SQL-Manual/Having-Clause.md) -- **FILL Clause**: Handles missing values in query results by specifying fill methods (e.g., previous non-null value or linear interpolation) for better visualization and analysis. Details:[FILL Clause](../SQL-Manual/Fill-Clause.md) -- **ORDER BY Clause**: Sorts query results in ascending (`ASC`) or descending (`DESC`) order, with optional handling for null values (`NULLS FIRST` or `NULLS LAST`). Details: [ORDER BY Clause](../SQL-Manual/OrderBy-Clause.md) +- **FILL Clause**: Handles missing values in query results by specifying fill methods (e.g., previous non-null value or linear interpolation) for better visualization and analysis. Details:[FILL Clause](../SQL-Manual/Fill-Clause_apache.md) +- **ORDER BY Clause**: Sorts query results in ascending (`ASC`) or descending (`DESC`) order, with optional handling for null values (`NULLS FIRST` or `NULLS LAST`). Details: [ORDER BY Clause](../SQL-Manual/OrderBy-Clause_apache.md) - **OFFSET Clause**: Specifies the starting position for the query result, skipping the first `OFFSET` rows. Often used with the `LIMIT` clause. Details: [LIMIT and OFFSET Clause](../SQL-Manual/Limit-Offset-Clause.md) - **LIMIT Clause**: Limits the number of rows in the query result. Typically used in conjunction with the `OFFSET` clause for pagination. Details: [LIMIT and OFFSET Clause](../SQL-Manual/Limit-Offset-Clause.md) diff --git a/src/UserGuide/latest-Table/SQL-Manual/Fill-Clause.md b/src/UserGuide/latest-Table/SQL-Manual/Fill-Clause_apache.md similarity index 53% rename from src/UserGuide/latest-Table/SQL-Manual/Fill-Clause.md rename to src/UserGuide/latest-Table/SQL-Manual/Fill-Clause_apache.md index ed6c776bb..d644edaff 100644 --- a/src/UserGuide/latest-Table/SQL-Manual/Fill-Clause.md +++ b/src/UserGuide/latest-Table/SQL-Manual/Fill-Clause_apache.md @@ -21,17 +21,14 @@ # FILL Clause - ## 1. Function Introduction During data queries, you may encounter scenarios where certain columns have missing data in some rows, resulting in NULL values in the result set. These NULL values can hinder data visualization and analysis. To address this, IoTDB provides the FILL clause to populate these NULL values. -- If the query includes an `ORDER BY` clause, the FILL clause is executed before `ORDER BY`. -- If a `GAPFILL` (e.g., `date_bin_gapfill` function) operation exists, the FILL clause is executed after `GAPFILL`. +When the query contains an `ORDER BY` clause, the FILL clause is executed before `ORDER BY`. If a `GAPFILL` (`date_bin_gapfill` function) operation exists, the FILL clause is executed after `GAPFILL`. ## 2. Syntax Overview - ```sql fillClause : FILL METHOD fillMethod @@ -40,6 +37,7 @@ fillClause fillMethod : LINEAR timeColumnClause? fillGroupClause? #linearFill | PREVIOUS timeBoundClause? timeColumnClause? fillGroupClause? #previousFill + | NEXT timeBoundClause? timeColumnClause? fillGroupClause? #nextFill | CONSTANT literalExpression #valueFill ; @@ -63,52 +61,52 @@ intervalField ; ``` -### 2.1 ### Filling Methods +### 2.1 Filling Methods -IoTDB supports the following three methods to fill NULL values: +IoTDB supports the following four methods to fill NULL values: -1. **PREVIOUS Fill:** Uses the most recent non-NULL value from the same column to fill NULL values. Starting from V2.0.8, only this method supports the OBJECT type. -2. **LINEAR Fill:** Applies linear interpolation using the nearest previous and next non-NULL values in the same column. -3. **CONSTANT Fill:** Fills NULL values with a specified constant. +1. **`PREVIOUS` Fill:** Uses the previous non-NULL value in the same column to fill NULL values. +2. **`NEXT` Fill:** Uses the next non-NULL value in the same column to fill NULL values. +3. **`LINEAR` Fill:** Applies linear interpolation using the previous and next non-NULL values in the same column. +4. **`CONSTANT` Fill:** Fills NULL values with a specified constant. Only one filling method can be specified, and it applies to all columns in the result set. - ### 2.2 Supported Data Types for Filling Methods -| Data Type | Previous | Linear | Constant | -| :-------- | :------- | :----- | :------- | -| boolean | √ | - | √ | -| int32 | √ | √ | √ | -| int64 | √ | √ | √ | -| float | √ | √ | √ | -| double | √ | √ | √ | -| text | √ | - | √ | -| string | √ | - | √ | -| blob | √ | - | √ | -| timestamp | √ | √ | √ | -| date | √ | √ | √ | +| Data Type | Previous | Next | Linear | Constant | +| :-------- | :------- | :--- | :----- | :------- | +| boolean | √ | √ | - | √ | +| int32 | √ | √ | √ | √ | +| int64 | √ | √ | √ | √ | +| float | √ | √ | √ | √ | +| double | √ | √ | √ | √ | +| text | √ | √ | - | √ | +| string | √ | √ | - | √ | +| blob | √ | √ | - | √ | +| timestamp | √ | √ | √ | √ | +| date | √ | √ | √ | √ | +| OBJECT | √ | √ | - | - | **Note:** Columns with data types not supporting the specified filling method will remain unchanged without errors. ## 3. Sample Dataset - -The [Example Data page](../Reference/Sample-Data.md)page provides SQL statements to construct table schemas and insert data. By downloading and executing these statements in the IoTDB CLI, you can import the data into IoTDB. This data can be used to test and run the example SQL queries included in this documentation, allowing you to reproduce the described results. +The [Example Data page](../Reference/Sample-Data.md) provides SQL statements to construct table schemas and insert data. By downloading and executing these statements in the IoTDB CLI, you can import the data into IoTDB. This data can be used to test and run the example SQL queries included in this documentation, allowing you to reproduce the described results. ### 3.1 PREVIOUS Fill -`PREVIOUS FILL` fills NULL values with the most recent non-NULL value in the same column. +For NULL values in the query result set, the previous non-NULL value of the same column is used for filling. #### 3.1.1 Parameters -- **TIME_BOUND (optional):** Defines a forward-looking time threshold. If the time difference between the current NULL value and the previous non-NULL value exceeds this threshold, the value will not be filled. By default, the system uses the first `TIMESTAMP` column in the query result to determine the threshold. - - Format: A time interval specified with integer values and units, e.g., `1d1h` (1 day and 1 hour). -- **TIME_COLUMN (optional):** Allows specifying the `TIMESTAMP` column used to determine the time threshold. The column is specified using its positional index (starting from 1) in the original table. +- **TIME_BOUND (optional):** A forward-looking time threshold. If the time difference between the current NULL value and the previous non-NULL value exceeds this threshold, the value will not be filled. By default, the system uses the first `TIMESTAMP` column in the query result to determine whether the threshold is exceeded. + - The time threshold is specified as a time interval. The numeric part must be an integer, and the unit part can be `y` (year), `mo` (month), `w` (week), `d` (day), `h` (hour), `m` (minute), `s` (second), `ms` (millisecond), `µs` (microsecond), or `ns` (nanosecond), e.g., `1d1h`. +- **TIME_COLUMN (optional):** Allows manually specifying the `TIMESTAMP` column used to determine the time threshold. The column is specified by appending a number (starting from 1) after the `TIME_COLUMN` parameter, which represents the positional index of the `TIMESTAMP` column in the original table. #### 3.1.2 Examples -- Without FILL Clause: +Without any filling method: ```sql SELECT time, temperature, status @@ -135,7 +133,7 @@ Total line number = 7 It costs 0.088s ``` -- Using `PREVIOUS Fill`: +Using the `PREVIOUS` fill method (NULL values will be filled with the previous non-NULL value): ```sql SELECT time, temperature, status @@ -163,22 +161,22 @@ Total line number = 7 It costs 0.091s ``` -- Using `PREVIOUS Fill` with a Specified Time Threshold: +Using the `PREVIOUS` fill method (with a specified time threshold): ```sql -# Do not specify a time column +-- Do not specify a time column SELECT time, temperature, status FROM table1 WHERE time >= 2024-11-27 00:00:00 and time <= 2024-11-29 00:00:00 AND plant_id='1001' and device_id='101' FILL METHOD PREVIOUS TIME_BOUND 1m; -# Manually specify the time column +-- Manually specify the time column SELECT time, temperature, status FROM table1 WHERE time >= 2024-11-27 00:00:00 and time <= 2024-11-29 00:00:00 AND plant_id='1001' and device_id='101' - FILL METHOD PREVIOUS 1m TIME_COLUMN 1; + FILL METHOD PREVIOUS TIME_BOUND 1m TIME_COLUMN 1; ``` Results: @@ -199,24 +197,132 @@ Total line number = 7 It costs 0.075s ``` -### 3.2 LINEAR Fill +### 3.2 NEXT Fill + +For NULL values in the query result set, the next non-NULL value of the same column is used for filling. (Supported since V2.0.11) + +#### 3.2.1 Parameters + +- **TIME_BOUND (optional):** A backward-looking time threshold. If the time difference between the current NULL value and the next non-NULL value exceeds this threshold, the value will not be filled. If this parameter is specified, the system automatically selects the first column in the `SELECT` clause whose return type is `TIMESTAMP` as the time column for threshold checking. +- **FILL_GROUP (optional):** Specifies grouping columns; filling only occurs within the same group. If this parameter is specified, the system automatically selects the first column in the `SELECT` clause whose return type is `TIMESTAMP` as the time column for sorting within each group. +- **TIME_COLUMN (optional):** Allows manually specifying the `TIMESTAMP` column used to determine the time threshold. The column is specified by appending a number (starting from 1) after the `TIME_COLUMN` parameter, which represents the positional index of the column in the `SELECT` list. + +**Notes:** + +- If neither `TIME_BOUND` nor `FILL_GROUP` is specified but `TIME_COLUMN` is specified, a syntax error will be thrown. +- If `TIME_BOUND` or `FILL_GROUP` is specified but `TIME_COLUMN` is not, and no `TIMESTAMP`-type column exists in the `SELECT` clause, an exception will be thrown. +- If the specified `TIME_COLUMN` column is not of `TIMESTAMP` type, or the specified position is out of the range of the `SELECT` list, an exception will be thrown. + +#### 3.2.2 Examples + +Without any filling method: + +```sql +SELECT time, temperature, status + FROM table1 + WHERE time >= 2024-11-27 00:00:00 and time <= 2024-11-29 00:00:00 + AND plant_id='1001' and device_id='101'; +``` + +Results: + +```sql ++-----------------------------+-----------+------+ +| time|temperature|status| ++-----------------------------+-----------+------+ +|2024-11-27T16:38:00.000+08:00| null| true| +|2024-11-27T16:39:00.000+08:00| 85.0| null| +|2024-11-27T16:40:00.000+08:00| 85.0| null| +|2024-11-27T16:41:00.000+08:00| 85.0| null| +|2024-11-27T16:42:00.000+08:00| null| false| +|2024-11-27T16:43:00.000+08:00| null| false| +|2024-11-27T16:44:00.000+08:00| null| false| ++-----------------------------+-----------+------+ +Total line number = 7 +It costs 0.061s +``` + +Using the `NEXT` fill method (NULL values will be filled with the next non-NULL value): + +```sql +SELECT time, temperature, status + FROM table1 + WHERE time >= 2024-11-27 00:00:00 and time <= 2024-11-29 00:00:00 + AND plant_id='1001' and device_id='101' + FILL METHOD NEXT; +``` + +Results: + +```sql ++-----------------------------+-----------+------+ +| time|temperature|status| ++-----------------------------+-----------+------+ +|2024-11-27T16:38:00.000+08:00| 85.0| true| +|2024-11-27T16:39:00.000+08:00| 85.0| false| +|2024-11-27T16:40:00.000+08:00| 85.0| false| +|2024-11-27T16:41:00.000+08:00| 85.0| false| +|2024-11-27T16:42:00.000+08:00| null| false| +|2024-11-27T16:43:00.000+08:00| null| false| +|2024-11-27T16:44:00.000+08:00| null| false| ++-----------------------------+-----------+------+ +Total line number = 7 +It costs 0.033s +``` + +Using the `NEXT` fill method (with a specified time threshold): + +```sql +-- Do not specify a time column +SELECT time, temperature, status + FROM table1 + WHERE time >= 2024-11-27 00:00:00 and time <= 2024-11-29 00:00:00 + AND plant_id='1001' and device_id='101' + FILL METHOD NEXT TIME_BOUND 1m; + +-- Manually specify the time column +SELECT time, temperature, status + FROM table1 + WHERE time >= 2024-11-27 00:00:00 and time <= 2024-11-29 00:00:00 + AND plant_id='1001' and device_id='101' + FILL METHOD NEXT TIME_BOUND 1m TIME_COLUMN 1; +``` + +Results: + +```sql ++-----------------------------+-----------+------+ +| time|temperature|status| ++-----------------------------+-----------+------+ +|2024-11-27T16:38:00.000+08:00| 85.0| true| +|2024-11-27T16:39:00.000+08:00| 85.0| null| +|2024-11-27T16:40:00.000+08:00| 85.0| null| +|2024-11-27T16:41:00.000+08:00| 85.0| false| +|2024-11-27T16:42:00.000+08:00| null| false| +|2024-11-27T16:43:00.000+08:00| null| false| +|2024-11-27T16:44:00.000+08:00| null| false| ++-----------------------------+-----------+------+ +Total line number = 7 +It costs 0.047s +``` -`LINEAR Fill` fills NULL values using linear interpolation based on the nearest previous and next non-NULL values in the same column. +### 3.3 LINEAR Fill -#### 3.2.1 Linear Fill Rules +For NULL values in the query result set, linear interpolation based on the previous and next non-NULL values of the same column is used for filling. -1. If all previous or all subsequent values are NULL, no filling is performed. -2. Columns with data types such as `boolean`, `string`, `blob`, or `text` are not filled, and no error is returned. -3. If no auxiliary time column is specified, the first `TIMESTAMP`-type column in the `SELECT` clause is used by default for interpolation. If no `TIMESTAMP` column exists, an error will be returned. +#### 3.3.1 Linear Fill Rules -#### 3.2.2 Parameters +- If all previous values or all subsequent values are NULL, no filling is performed. +- Columns with data types such as `boolean`, `string`, `blob`, or `text` are not filled, and no error is returned. +- If no time column is specified, the first `TIMESTAMP`-type column in the `SELECT` clause is used by default as the auxiliary time column for linear interpolation. If no `TIMESTAMP`-type column exists, an exception will be thrown. -- **TIME_COLUMN (optional):** Specifies the `TIMESTAMP` column to be used as an auxiliary column for linear interpolation. The column is identified by its positional index (starting from 1) in the original table. +#### 3.3.2 Parameters -**Note:** The auxiliary column used for linear interpolation is not required to be the `time` column. However, the auxiliary column must be sorted in ascending or descending order for meaningful interpolation. If another column is specified, the user must ensure the result set is ordered correctly. +- **TIME_COLUMN (optional):** Allows manually specifying the `TIMESTAMP` column used as the auxiliary column for linear interpolation. The column is specified by appending a number (starting from 1) after the `TIME_COLUMN` parameter, which represents the positional index of the `TIMESTAMP` column in the original table. -#### 3.2.3 Examples +**Note:** The auxiliary column used for linear interpolation is not required to be the `time` column. Any expression of `TIMESTAMP` type can be used. However, since linear interpolation is only meaningful when the auxiliary column is sorted in ascending or descending order, if another column is specified, the user must ensure the result set is ordered by that column in ascending or descending order. +#### 3.3.3 Examples ```sql SELECT time, temperature, status @@ -226,7 +332,7 @@ SELECT time, temperature, status FILL METHOD LINEAR; ``` -Result: +Results: ```sql +-----------------------------+-----------+------+ @@ -244,20 +350,18 @@ Total line number = 7 It costs 0.053s ``` -### 3.3 ### CONSTANT Fill +### 3.4 CONSTANT Fill -`CONSTANT Fill` fills NULL values with a specified constant value. +For NULL values in the query result set, a specified constant is used for filling. -#### 3.3.1 Constant Fill Rules +#### 3.4.1 Constant Fill Rules -1. If the data type of the constant does not match the column's data type, IoTDB does not fill the result set and no error is returned. -2. If the constant value exceeds the column's allowable range, IoTDB does not fill the result set and no error is returned. +- If the data type of the constant does not match the column's data type, IoTDB does not fill the query result, and no error is returned. +- If the constant value exceeds the maximum value that the data type can represent, IoTDB does not fill the query result, and no error is returned. +#### 3.4.2 Examples -#### 3.3.2 Examples - -- Using a `FLOAT` constant: - +Using a `FLOAT` constant: ```sql SELECT time, temperature, status @@ -285,7 +389,7 @@ Total line number = 7 It costs 0.242s ``` -W- Using a `BOOLEAN` constant: +Using a `BOOLEAN` constant: ```sql SELECT time, temperature, status @@ -315,13 +419,12 @@ It costs 0.073s ## 4. Advanced Usage -When using the `PREVIOUS` or `LINEAR` FILL methods, the `FILL_GROUP` parameter allows filling within specific groups without being influenced by other groups. +When using `PREVIOUS`, `NEXT`, or `LINEAR` FILL, an additional `FILL_GROUP` parameter is supported to perform filling within groups. -#### Examples +When using the GROUP BY clause together with FILL, you may want to fill NULL values within each group without being affected by other groups. -- **Filling Missing Values Within `device_id`** +For example, fill the NULL values within each `device_id` group without using values from other devices: -The following query demonstrates how to fill missing values for each `device_id` group independently, without using values from other devices: ```sql SELECT date_bin(1h, time) AS hour_time, plant_id, device_id, avg(temperature) AS avg_temp FROM table1 @@ -329,7 +432,7 @@ SELECT date_bin(1h, time) AS hour_time, plant_id, device_id, avg(temperature) A group by 1, plant_id, device_id; ``` -Results: +Results: ```sql +-----------------------------+--------+---------+--------+ @@ -348,9 +451,7 @@ Total line number = 8 It costs 0.110s ``` -- **Without Specifying `FILL_GROUP`** - -If the `FILL_GROUP` parameter is not specified, missing values in `device_id = 100` will be filled using values from `device_id = 101`: +If the `FILL_GROUP` parameter is not specified, the NULL values of `100` will be filled with the values of `101`: ```sql SELECT date_bin(1h, time) AS hour_time, plant_id, device_id, avg(temperature) AS avg_temp @@ -360,7 +461,7 @@ SELECT date_bin(1h, time) AS hour_time, plant_id, device_id, avg(temperature) A FILL METHOD PREVIOUS; ``` -Results: +Results: ```sql +-----------------------------+--------+---------+--------+ @@ -379,9 +480,7 @@ Total line number = 8 It costs 0.066s ``` -- **Specifying `FILL_GROUP` for Grouped Filling** - -By specifying `FILL_GROUP 2`, the filling is restricted to groups based on the second column (`device_id`). As a result, missing values in `device_id = 100` will not be filled using values from `device_id = 101`: +After specifying `FILL_GROUP` as the 2nd column, filling only occurs within groups keyed by the second column `device_id`. The NULL values of `100` will not be filled with the values of `101`, because they belong to different groups. ```sql SELECT date_bin(1h, time) AS hour_time, plant_id, device_id, avg(temperature) AS avg_temp @@ -412,16 +511,12 @@ It costs 0.089s ## 5. Special Notes -When using `LINEAR` or `PREVIOUS` FILL methods, if the auxiliary time column (used to determine filling logic) contains NULL values, IoTDB follows these rules: +When using `LINEAR FILL`, `PREVIOUS FILL`, or `NEXT FILL`, if the auxiliary time column (the time column used to determine the filling logic) contains NULL values, IoTDB follows these rules: -- Rows with NULL values in the auxiliary column will not be filled. +- Rows whose auxiliary time column is NULL will not be filled. - These rows are also excluded from the filling logic calculations. -**Example of `PREVIOUS Fill`** - -- Query original data: - - +Taking `PREVIOUS FILL` as an example, the original data is as follows: ```sql SELECT time, plant_id, device_id, humidity, arrival_time @@ -448,7 +543,7 @@ Total line number = 7 It costs 0.119s ``` -- Using `arrival_time` as the auxiliary column with a time interval (`TIME_BOUND`) of 2 seconds +Using the `arrival_time` column as the auxiliary time column, with a time interval (`TIME_BOUND`) of 2 seconds (values are not filled if the previous non-NULL value is more than 2 seconds away from the current value): ```sql SELECT time, plant_id, device_id, humidity, arrival_time @@ -475,15 +570,9 @@ Results: Total line number = 7 It costs 0.049s ``` -**Filling Details** - -1. For `humidity` at `16:39`, `16:42`, and `16:43`: - 1. Since the auxiliary column `arrival_time` is NULL, no filling is performed. -2. For `humidity` at `16:40`: - 1. The auxiliary column `arrival_time` is not NULL and has a value of `1970-01-01T08:00:00.003+08:00`. - 2. The time difference from the previous non-NULL value (`1970-01-01T08:00:00.001+08:00`) is less than 2 seconds (`TIME_BOUND`) - 3. So the value `35.1` from the first row is used for filling. -3. For `humidity` at `16:41`: - 1. Although the auxiliary column `arrival_time` is not NULL, the time difference from the previous non-NULL value exceeds 2 seconds, so no filling is performed. -4. For `humidity` at `16:44`: - 1. Similarly, the time difference exceeds 2 seconds, so no filling is performed. \ No newline at end of file + +Filling details: + +- For the `humidity` column at 16:39, 16:42, and 16:43: since the auxiliary column `arrival_time` is NULL, no filling is performed. +- For the `humidity` column at 16:40: the auxiliary column `arrival_time` is not NULL (`1970-01-01T08:00:00.003+08:00`), and the time difference from the previous non-NULL value (`1970-01-01T08:00:00.001+08:00`) does not exceed 2 seconds, so the value `35.1` of the first row is used for filling. +- For the `humidity` column at 16:41: although `arrival_time` is not NULL, the time difference from the previous non-NULL value exceeds 2 seconds, so no filling is performed. The same applies to the seventh row. diff --git a/src/UserGuide/Master/Table/SQL-Manual/GroupBy-Clause.md b/src/UserGuide/latest-Table/SQL-Manual/GroupBy-Clause_apache.md similarity index 56% rename from src/UserGuide/Master/Table/SQL-Manual/GroupBy-Clause.md rename to src/UserGuide/latest-Table/SQL-Manual/GroupBy-Clause_apache.md index 253009fcb..cb4324fb3 100644 --- a/src/UserGuide/Master/Table/SQL-Manual/GroupBy-Clause.md +++ b/src/UserGuide/latest-Table/SQL-Manual/GroupBy-Clause_apache.md @@ -27,26 +27,24 @@ GROUP BY expression (',' expression)* ``` -- The `GROUP BY` clause is used to group the result set of a `SELECT` statement based on the specified column values. The values of the grouping columns remain unchanged in the results, while other columns with the same grouping column values are calculated using specified aggregate functions (e.g., `COUNT`, `AVG`). +- The GROUP BY clause is used to group the result set of a SELECT statement by the values of the specified columns for aggregated computation. The values of these grouping columns are kept as-is in the result, while all other records that share the same grouping column values are computed through the specified aggregate functions (e.g., COUNT, AVG). ![](/img/groupby01.png) ## 2. Notes -#### 2.1 Items in the `SELECT` Clause +- Items in the SELECT clause must either contain aggregate functions or consist of columns that appear in the GROUP BY clause. -Items in the `SELECT` clause must either include aggregate functions or consist of columns specified in the `GROUP BY` clause. - -Valid Example: +Valid example: ```sql SELECT concat(device_id, model_id), avg(temperature) FROM table1 - GROUP BY device_id, model_id; -- valid + GROUP BY device_id, model_id; ``` -Result: +Results: ```sql +-----+-----+ @@ -63,48 +61,46 @@ Total line number = 6 It costs 0.094s ``` -Invalid Example 1: +Invalid example 1: ```sql SELECT device_id, temperature FROM table1 - GROUP BY device_id;-- invalid + GROUP BY device_id; ``` -Error Message: +Results: ```sql Msg: org.apache.iotdb.jdbc.IoTDBSQLException: 701: 'temperature' must be an aggregate expression or appear in GROUP BY clause ``` -Invalid Example 2: +Invalid example 2: ```sql SELECT device_id, avg(temperature) FROM table1 - GROUP BY model; -- invalid + GROUP BY model; ``` -Error Message: +Results: ```sql Msg: org.apache.iotdb.jdbc.IoTDBSQLException: 701: Column 'model' cannot be resolved ``` -#### 2.2 Without a `GROUP BY` Clause +- If there is no GROUP BY clause, all items in the SELECT clause must either contain aggregate functions or contain no aggregate functions at all. -If there is no `GROUP BY` clause, all items in the `SELECT` clause must either include aggregate functions or exclude them entirely. - -Valid Example: +Valid example: ```sql SELECT COUNT(*), avg(temperature) - FROM table1; -- valid + FROM table1; ``` -Result: +Results: ```sql +-----+-----------------+ @@ -116,24 +112,20 @@ Total line number = 1 It costs 0.094s ``` -Invalid Example: +Invalid example: ```sql -SELECT humidity, avg(temperature) FROM table1; -- invalid +SELECT humidity, avg(temperature) FROM table1; ``` -Result: +Results: ```sql Msg: org.apache.iotdb.jdbc.IoTDBSQLException: 701: 'humidity' must be an aggregate expression or appear in GROUP BY clause ``` -#### 2.3 Using Constant Integers in `GROUP BY` Clause - -The `GROUP BY` clause supports referencing `SELECT` items using constant integers starting from 1. If the constant is less than 1 or exceeds the size of the `SELECT` item list, an error will occur. - -Example: +- The GROUP BY clause can use constant integers starting from 1 to reference items in the SELECT clause. If the constant integer is less than 1 or greater than the size of the select item list, an error will be thrown. ```sql SELECT date_bin(1h, time), device_id, avg(temperature) @@ -142,7 +134,7 @@ SELECT date_bin(1h, time), device_id, avg(temperature) GROUP BY 1, device_id; ``` -Result: +Results: ```sql +-----------------------------+---------+-----+ @@ -158,11 +150,7 @@ Total line number = 5 It costs 0.092s ``` -#### 2.4 Alias Restrictions in `GROUP BY` Clause - -Aliases from `SELECT` items cannot be used in the `GROUP BY` clause. Use the original expression instead. - -Example: +- In versions prior to V2.0.11, using the alias of a select item in the GROUP BY clause was not supported. You needed to use the complete expression (or the constant index of the select item) instead, as shown in the following SQL: ```sql SELECT date_bin(1h, time) AS hour_time, device_id, avg(temperature) @@ -171,7 +159,7 @@ SELECT date_bin(1h, time) AS hour_time, device_id, avg(temperature) GROUP BY date_bin(1h, time), device_id; ``` -Result: +Results: ```sql +-----------------------------+---------+-----+ @@ -187,17 +175,71 @@ Total line number = 5 It costs 0.092s ``` -#### 2.5 Using Aggregate Functions with `\*` +- Since V2.0.11, the GROUP BY clause supports referencing aliases explicitly defined in the SELECT clause. + - This capability only applies when directly referencing the alias itself; names with table name prefixes (e.g., `GROUP BY table1.hour_time`) are not expanded as SELECT aliases and are still resolved as regular expressions. + - A name referenced in GROUP BY is first resolved as an input column of the current query; only when it cannot be resolved as an input column will it be further resolved as a SELECT alias. If multiple aliases with the same name exist in the SELECT list, an ambiguity error will be thrown when referencing that alias. + - After alias resolution in GROUP BY, the existing GROUP BY validation rules still apply. For example, grouping keys cannot contain aggregate functions, window functions, or grouping functions. + +Valid example: + +```sql +SELECT date_bin(1h, time) AS hour_time, device_id, avg(temperature) + FROM table1 + WHERE time >= 2024-11-27 00:00:00 and time <= 2024-11-29 00:00:00 + GROUP BY hour_time, device_id; +``` + +Results: -Only the `COUNT` function can be used with `*` to calculate the total number of rows. Using `*` with other aggregate functions will result in an error. +```sql ++-----------------------------+---------+-----+ +| hour_time|device_id|_col2| ++-----------------------------+---------+-----+ +|2024-11-28T08:00:00.000+08:00| 100| 85.0| +|2024-11-28T09:00:00.000+08:00| 100| null| +|2024-11-28T10:00:00.000+08:00| 100| 85.0| +|2024-11-28T11:00:00.000+08:00| 100| 88.0| +|2024-11-27T16:00:00.000+08:00| 101| 85.0| ++-----------------------------+---------+-----+ +Total line number = 5 +It costs 0.228s +``` -Example: +Invalid example 1: multiple aliases with the same name in one statement + +```sql +SELECT temperature AS value, humidity AS value + FROM table1 + GROUP BY value; +``` + +Results: + +```sql +Msg: org.apache.iotdb.jdbc.IoTDBSQLException: 701: Column alias 'value' is ambiguous at positions 1, 2 +``` + +Invalid example 2: grouping keys containing aggregate functions + +```sql +SELECT AVG(temperature) AS avg_temperature + FROM table1 + GROUP BY avg_temperature; +``` + +Results: + +```sql +Msg: org.apache.iotdb.jdbc.IoTDBSQLException: 701: GROUP BY clause cannot contain aggregations, window functions or grouping operations: [AVG(temperature)] +``` + +- Only the COUNT function can be used with an asterisk (`*`) to count the total number of rows in a table. Using other aggregate functions with `*` will throw an error. ```sql SELECT count(*) FROM table1; ``` -Result: +Results: ```sql +-----+ @@ -209,13 +251,13 @@ Total line number = 1 It costs 0.047s ``` -## 3. Sample Data and Usage Examples +## 3. Sample Dataset -The [Example Data page](../Reference/Sample-Data.md)page provides SQL statements to construct table schemas and insert data. By downloading and executing these statements in the IoTDB CLI, you can import the data into IoTDB. This data can be used to test and run the example SQL queries included in this documentation, allowing you to reproduce the described results. +The [Example Data page](../Reference/Sample-Data.md) provides SQL statements to construct table schemas and insert data. By downloading and executing these statements in the IoTDB CLI, you can import the data into IoTDB. This data can be used to test and run the example SQL queries included in this documentation, allowing you to reproduce the described results. -#### Example 1: Downsampling Time-Series Data +#### Example 1: Downsampling Time Series Data -Downsample the temperature of device `101` over the specified time range, returning one average temperature per hour: +Downsample the temperature of device 101 over the following time range, returning an average temperature per hour. ```sql SELECT date_bin(1h, time) AS hour_time, AVG(temperature) AS avg_temperature @@ -225,7 +267,17 @@ SELECT date_bin(1h, time) AS hour_time, AVG(temperature) AS avg_temperature GROUP BY 1; ``` -Result: +Since V2.0.11, GROUP BY items can directly reference aliases explicitly defined in the SELECT clause, so the SQL above can be written as: + +```sql +SELECT date_bin(1h, time) AS hour_time, AVG(temperature) AS avg_temperature + FROM table1 + WHERE time >= 2024-11-27 00:00:00 and time <= 2024-11-30 00:00:00 + AND device_id='101' + GROUP BY hour_time; +``` + +Results: ```sql +-----------------------------+---------------+ @@ -238,7 +290,7 @@ Total line number = 2 It costs 0.054s ``` -Downsample the temperature of all devices over the past day, returning one average temperature per hour for each device: +Downsample the temperature of each device over the past day, returning an average temperature per hour. ```sql SELECT date_bin(1h, time) AS hour_time, device_id, AVG(temperature) AS avg_temperature @@ -247,7 +299,7 @@ SELECT date_bin(1h, time) AS hour_time, device_id, AVG(temperature) AS avg_tempe GROUP BY 1, device_id; ``` -Result: +Results: ```sql +-----------------------------+---------+---------------+ @@ -266,10 +318,9 @@ Total line number = 8 It costs 0.081s ``` - For more details on the `date_bin` function, refer to the **[Definition of Date Bin (Time Bucketing)](../SQL-Manual/Featured-Functions.md#_1-1-date-bin-function)** feature documentation. -#### Example 2: Query the Latest Data Point for Each Device +#### Example 2: Querying the Latest Data Point of Each Device ```sql SELECT device_id, LAST(temperature), LAST_BY(time, temperature) @@ -277,7 +328,7 @@ SELECT device_id, LAST(temperature), LAST_BY(time, temperature) GROUP BY device_id; ``` -Result: +Results: ```sql +---------+-----+-----------------------------+ @@ -290,15 +341,15 @@ Total line number = 2 It costs 0.078s ``` -#### Example 3: Count Total Rows +#### Example 3: Counting Total Rows -Count the total number of rows for all devices: +Count the total number of rows of all devices: ```sql SELECT COUNT(*) FROM table1; ``` -Result: +Results: ```sql +-----+ @@ -310,7 +361,7 @@ Total line number = 1 It costs 0.060s ``` -Count the total number of rows for each device: +Count the total number of rows of each device: ```sql SELECT device_id, COUNT(*) AS total_rows @@ -318,7 +369,7 @@ SELECT device_id, COUNT(*) AS total_rows GROUP BY device_id; ``` -Result: +Results: ```sql +---------+----------+ @@ -331,7 +382,7 @@ Total line number = 2 It costs 0.060s ``` -#### Example 4: Aggregate without a `GROUP BY` Clause +#### Example 4: Aggregation Without a GROUP BY Clause Query the maximum temperature across all devices: @@ -340,7 +391,7 @@ SELECT MAX(temperature) FROM table1; ``` -Result: +Results: ```sql +-----+ @@ -352,9 +403,9 @@ Total line number = 1 It costs 0.086s ``` -#### Example 5: Aggregate Results from a Subquery +#### Example 5: Aggregating the Results of a Subquery -Query the combinations of plants and devices where the average temperature exceeds 80.0 over a specified time range and has at least two records: +Query the plant and device combinations whose average temperature exceeds 80.0 with at least two records during the specified time period: ```sql SELECT plant_id, device_id @@ -367,7 +418,7 @@ GROUP BY plant_id, device_id HAVING COUNT(*) > 1; ``` -Result: +Results: ```sql +--------+---------+ @@ -378,4 +429,4 @@ Result: +--------+---------+ Total line number = 2 It costs 0.073s -``` \ No newline at end of file +``` diff --git a/src/UserGuide/latest-Table/SQL-Manual/OrderBy-Clause.md b/src/UserGuide/latest-Table/SQL-Manual/OrderBy-Clause_apache.md similarity index 74% rename from src/UserGuide/latest-Table/SQL-Manual/OrderBy-Clause.md rename to src/UserGuide/latest-Table/SQL-Manual/OrderBy-Clause_apache.md index a9348f990..829ad24fe 100644 --- a/src/UserGuide/latest-Table/SQL-Manual/OrderBy-Clause.md +++ b/src/UserGuide/latest-Table/SQL-Manual/OrderBy-Clause_apache.md @@ -19,9 +19,7 @@ --> -# ORDER BY Clauses - -The `ORDER BY` clause is used to sort the result set of a query at its final stage based on specified sorting conditions. +# ORDER BY Clause ## 1. Syntax Overview @@ -33,19 +31,19 @@ sortItem ; ``` -### 1.1 ORDER BY Clauses - -- Allows sorting query result rows based on specified conditions in ascending order (`ASC`) or descending order (`DESC`). -- Provides control over the position of `NULL` values, enabling users to specify whether `NULL` values appear at the beginning (`NULLS FIRST`) or the end (`NULLS LAST`). -- By default, sorting is applied as `ASC NULLS LAST`, meaning values are sorted in ascending order and `NULL` values are placed at the end. Users can manually specify other parameters to override the default behavior. -- The `ORDER BY` clause is executed before the `LIMIT` or `OFFSET` clauses. +### 1.1 ORDER BY Clause -## 2. Example Data +- Used to sort the result set at the final stage of a query. Based on the specified sorting conditions, the rows in the query result can be arranged in ascending (ASC) or descending (DESC) order. +- Provides control over the sorting position of NULL values, allowing users to specify whether NULL values are placed at the beginning (NULLS FIRST) or the end (NULLS LAST) of the result. +- By default, `ASC NULLS LAST` is used, i.e., values are sorted in ascending order with NULL values placed last. The default sorting order can be changed by manually specifying other parameters. +- The ORDER BY clause is executed before the LIMIT or OFFSET clause. +- Since V2.0.11, the ORDER BY clause supports referencing aliases explicitly defined in the SELECT clause. When a name is directly referenced in ORDER BY, it is first resolved as a SELECT output alias; if multiple aliases with the same name exist in the SELECT list, an ambiguity error will be thrown when referencing that alias. +## 2. Sample Dataset -The [Example Data page](../Reference/Sample-Data.md)page provides SQL statements to construct table schemas and insert data. By downloading and executing these statements in the IoTDB CLI, you can import the data into IoTDB. This data can be used to test and run the example SQL queries included in this documentation, allowing you to reproduce the described results. +The [Example Data page](../Reference/Sample-Data.md) provides SQL statements to construct table schemas and insert data. By downloading and executing these statements in the IoTDB CLI, you can import the data into IoTDB. This data can be used to test and run the example SQL queries included in this documentation, allowing you to reproduce the described results. -#### Example 1: Query data from the past hour in descending order of time +#### Example 1: Query Data of the Past Hour Sorted by Time in Descending Order ```sql SELECT * @@ -76,7 +74,7 @@ Total line number = 11 It costs 0.148s ``` -#### Example 2: Query data sorted by device_id in ascending order and time in descending order, with NULL temperatures displayed first +#### Example 2: Query Data of All Devices Sorted by device_id in Ascending Order and Time in Descending Order, with NULL temperature Displayed First ```sql SELECT * @@ -107,7 +105,7 @@ Total line number = 11 It costs 0.060s ``` -#### Example 3: Query the top 10 rows with the highest temperature values +#### Example 3: Query the Top 10 Rows with the Highest Temperature ```sql SELECT * @@ -135,4 +133,33 @@ Results: +-----------------------------+------+--------+---------+--------+-----------+-----------+--------+------+-----------------------------+ Total line number = 10 It costs 0.069s -``` \ No newline at end of file +``` + +#### Example 4: Aggregate by Time Bucket and Sort by Alias (via SELECT Alias) + +```sql +SELECT date_bin(1h, time) AS hour_time, AVG(temperature) AS avg_temperature + FROM table1 + WHERE time >= 2024-11-27 00:00:00 and time <= 2024-11-30 00:00:00 + GROUP BY hour_time + ORDER BY hour_time; +``` + +Results: + +```sql ++-----------------------------+---------------+ +| hour_time|avg_temperature| ++-----------------------------+---------------+ +|2024-11-27T16:00:00.000+08:00| 85.0| +|2024-11-28T08:00:00.000+08:00| 85.0| +|2024-11-28T09:00:00.000+08:00| null| +|2024-11-28T10:00:00.000+08:00| 85.0| +|2024-11-28T11:00:00.000+08:00| 88.0| +|2024-11-29T10:00:00.000+08:00| 85.0| +|2024-11-29T11:00:00.000+08:00| null| +|2024-11-29T18:00:00.000+08:00| 90.0| ++-----------------------------+---------------+ +Total line number = 8 +It costs 0.079s +``` diff --git a/src/UserGuide/latest-Table/SQL-Manual/Select-Clause_apache.md b/src/UserGuide/latest-Table/SQL-Manual/Select-Clause_apache.md index 3c70e6776..c7e4b12df 100644 --- a/src/UserGuide/latest-Table/SQL-Manual/Select-Clause_apache.md +++ b/src/UserGuide/latest-Table/SQL-Manual/Select-Clause_apache.md @@ -119,7 +119,7 @@ It costs 0.653s #### 3.1.2 Aggregate Functions -Aggregate functions summarize multiple rows into a single value. When aggregate functions are present in the `SELECT` clause, the query is treated as an **aggregate query**. All expressions in the query must either be part of an aggregate function or specified in the [GROUP BY clause](../SQL-Manual/GroupBy-Clause.md). +Aggregate functions summarize multiple rows into a single value. When aggregate functions are present in the `SELECT` clause, the query is treated as an **aggregate query**. All expressions in the query must either be part of an aggregate function or specified in the [GROUP BY clause](../SQL-Manual/GroupBy-Clause_apache.md). **Example 1**: Total number of rows in a table. diff --git a/src/UserGuide/latest-Table/SQL-Manual/overview_apache.md b/src/UserGuide/latest-Table/SQL-Manual/overview_apache.md index e6b98ca16..548e16ffa 100644 --- a/src/UserGuide/latest-Table/SQL-Manual/overview_apache.md +++ b/src/UserGuide/latest-Table/SQL-Manual/overview_apache.md @@ -40,10 +40,10 @@ The IoTDB table model query syntax supports the following clauses: - **SELECT Clause**: Specifies the columns to be included in the result. Details: [SELECT Clause](../SQL-Manual/Select-Clause_apache.md) - **FROM Clause**: Indicates the data source for the query, which can be a single table, multiple tables joined using the `JOIN` clause, or a subquery. Details: [FROM & JOIN Clause](../SQL-Manual/From-Join-Clause.md) - **WHERE Clause**: Filters rows based on specific conditions. Logically executed immediately after the `FROM` clause. Details: [WHERE Clause](../SQL-Manual/Where-Clause.md) -- **GROUP BY Clause**: Used for aggregating data, specifying the columns for grouping. Details: [GROUP BY Clause](../SQL-Manual/GroupBy-Clause.md) +- **GROUP BY Clause**: Used for aggregating data, specifying the columns for grouping. Details: [GROUP BY Clause](../SQL-Manual/GroupBy-Clause_apache.md) - **HAVING Clause**: Applied after the `GROUP BY` clause to filter grouped data, similar to `WHERE` but operates after grouping. Details:[HAVING Clause](../SQL-Manual/Having-Clause.md) -- **FILL Clause**: Handles missing values in query results by specifying fill methods (e.g., previous non-null value or linear interpolation) for better visualization and analysis. Details:[FILL Clause](../SQL-Manual/Fill-Clause.md) -- **ORDER BY Clause**: Sorts query results in ascending (`ASC`) or descending (`DESC`) order, with optional handling for null values (`NULLS FIRST` or `NULLS LAST`). Details: [ORDER BY Clause](../SQL-Manual/OrderBy-Clause.md) +- **FILL Clause**: Handles missing values in query results by specifying fill methods (e.g., previous non-null value or linear interpolation) for better visualization and analysis. Details:[FILL Clause](../SQL-Manual/Fill-Clause_apache.md) +- **ORDER BY Clause**: Sorts query results in ascending (`ASC`) or descending (`DESC`) order, with optional handling for null values (`NULLS FIRST` or `NULLS LAST`). Details: [ORDER BY Clause](../SQL-Manual/OrderBy-Clause_apache.md) - **OFFSET Clause**: Specifies the starting position for the query result, skipping the first `OFFSET` rows. Often used with the `LIMIT` clause. Details: [LIMIT and OFFSET Clause](../SQL-Manual/Limit-Offset-Clause.md) - **LIMIT Clause**: Limits the number of rows in the query result. Typically used in conjunction with the `OFFSET` clause for pagination. Details: [LIMIT and OFFSET Clause](../SQL-Manual/Limit-Offset-Clause.md) diff --git a/src/zh/UserGuide/Master/Table/Basic-Concept/Query-Data_apache.md b/src/zh/UserGuide/Master/Table/Basic-Concept/Query-Data_apache.md index f43389f74..20f9fe61f 100644 --- a/src/zh/UserGuide/Master/Table/Basic-Concept/Query-Data_apache.md +++ b/src/zh/UserGuide/Master/Table/Basic-Concept/Query-Data_apache.md @@ -40,10 +40,10 @@ IoTDB 查询语法提供以下子句: - SELECT 子句:查询结果应包含的列。详细语法见:[SELECT子句](../SQL-Manual/Select-Clause_apache.md) - FROM 子句:指出查询的数据源,可以是单个表、多个通过 `JOIN` 子句连接的表,或者是一个子查询。详细语法见:[FROM & JOIN 子句](../SQL-Manual/From-Join-Clause.md) - WHERE 子句:用于过滤数据,只选择满足特定条件的数据行。这个子句在逻辑上紧跟在 FROM 子句之后执行。详细语法见:[WHERE 子句](../SQL-Manual/Where-Clause.md) -- GROUP BY 子句:当需要对数据进行聚合时使用,指定了用于分组的列。详细语法见:[GROUP BY 子句](../SQL-Manual/GroupBy-Clause.md) +- GROUP BY 子句:当需要对数据进行聚合时使用,指定了用于分组的列。详细语法见:[GROUP BY 子句](../SQL-Manual/GroupBy-Clause_apache.md) - HAVING 子句:在 GROUP BY 子句之后使用,用于对已经分组的数据进行过滤。与 WHERE 子句类似,但 HAVING 子句在分组后执行。详细语法见:[HAVING 子句](../SQL-Manual/Having-Clause.md) -- FILL 子句:用于处理查询结果中的空值,用户可以使用 FILL 子句来指定数据缺失时的填充模式(如前一个非空值或线性插值)来填充 null 值,以便于数据可视化和分析。 详细语法见:[FILL 子句](../SQL-Manual/Fill-Clause.md) -- ORDER BY 子句:对查询结果进行排序,可以指定升序(ASC)或降序(DESC),以及 NULL 值的处理方式(NULLS FIRST 或 NULLS LAST)。详细语法见:[ORDER BY 子句](../SQL-Manual/OrderBy-Clause.md) +- FILL 子句:用于处理查询结果中的空值,用户可以使用 FILL 子句来指定数据缺失时的填充模式(如前一个非空值或线性插值)来填充 null 值,以便于数据可视化和分析。 详细语法见:[FILL 子句](../SQL-Manual/Fill-Clause_apache.md) +- ORDER BY 子句:对查询结果进行排序,可以指定升序(ASC)或降序(DESC),以及 NULL 值的处理方式(NULLS FIRST 或 NULLS LAST)。详细语法见:[ORDER BY 子句](../SQL-Manual/OrderBy-Clause_apache.md) - OFFSET 子句:用于指定查询结果的起始位置,即跳过前 OFFSET 行。与 LIMIT 子句配合使用。详细语法见:[LIMIT 和 OFFSET 子句](../SQL-Manual/Limit-Offset-Clause.md) - LIMIT 子句:限制查询结果的行数,通常与 OFFSET 子句一起使用以实现分页功能。详细语法见:[LIMIT 和 OFFSET 子句](../SQL-Manual/Limit-Offset-Clause.md) diff --git a/src/zh/UserGuide/Master/Table/SQL-Manual/Fill-Clause.md b/src/zh/UserGuide/Master/Table/SQL-Manual/Fill-Clause_apache.md similarity index 73% rename from src/zh/UserGuide/Master/Table/SQL-Manual/Fill-Clause.md rename to src/zh/UserGuide/Master/Table/SQL-Manual/Fill-Clause_apache.md index 1d89c3fc7..6ddf69686 100644 --- a/src/zh/UserGuide/Master/Table/SQL-Manual/Fill-Clause.md +++ b/src/zh/UserGuide/Master/Table/SQL-Manual/Fill-Clause_apache.md @@ -37,6 +37,7 @@ fillClause fillMethod : LINEAR timeColumnClause? fillGroupClause? #linearFill | PREVIOUS timeBoundClause? timeColumnClause? fillGroupClause? #previousFill + | NEXT timeBoundClause? timeColumnClause? fillGroupClause? #nextFill | CONSTANT literalExpression #valueFill ; @@ -62,28 +63,30 @@ intervalField ### 2.1 填充方式 -IoTDB 支持以下三种空值填充方式: +IoTDB 支持以下四种空值填充方式: -1. **`PREVIOUS`填充**:使用该列前一个非空值进行填充,V2.0.8 版本起仅该方式支持支持 OBJECT 类型。 -2. **`LINEAR`填充**:使用该列前一个非空值和下一个非空值的线性插值进行填充。 -3. **`Constant`填充**:使用指定的常量值进行填充。 +1. **`PREVIOUS` 填充**:使用该列前一个非空值进行填充。 +2. **`NEXT` 填充**:使用该列后一个非空值进行填充。 +3. **`LINEAR` 填充**:使用该列前一个非空值和下一个非空值的线性插值进行填充。 +4. **`CONSTANT` 填充**:使用指定的常量值进行填充。 只能指定一种填充方法,且该方法会作用于结果集的全部列。 ### 2.2 数据类型与支持的填充方法 -| Data Type | Previous | Linear | Constant | -| :-------- | :------- | :----- | :------- | -| boolean | √ | - | √ | -| int32 | √ | √ | √ | -| int64 | √ | √ | √ | -| float | √ | √ | √ | -| double | √ | √ | √ | -| text | √ | - | √ | -| string | √ | - | √ | -| blob | √ | - | √ | -| timestamp | √ | √ | √ | -| date | √ | √ | √ | +| Data Type | Previous | Next | Linear | Constant | +| :-------- | :------- | :--- | :----- | :------- | +| boolean | √ | √ | - | √ | +| int32 | √ | √ | √ | √ | +| int64 | √ | √ | √ | √ | +| float | √ | √ | √ | √ | +| double | √ | √ | √ | √ | +| text | √ | √ | - | √ | +| string | √ | √ | - | √ | +| blob | √ | √ | - | √ | +| timestamp | √ | √ | √ | √ | +| date | √ | √ | √ | √ | +| OBJECT | √ | √ | - | - | 注意:对于数据类型不支持指定填充方法的列,既不进行填充,也不抛出异常,只是保持原样。 @@ -173,7 +176,7 @@ SELECT time, temperature, status FROM table1 WHERE time >= 2024-11-27 00:00:00 and time <= 2024-11-29 00:00:00 AND plant_id='1001' and device_id='101' - FILL METHOD PREVIOUS 1m TIME_COLUMN 1; + FILL METHOD PREVIOUS TIME_BOUND 1m TIME_COLUMN 1; ``` 查询结果: @@ -194,23 +197,132 @@ Total line number = 7 It costs 0.075s ``` -### 3.2 LINEAR 填充 +### 3.2 NEXT 填充 + +对于查询结果集中的空值,使用该列的后一个非空值进行填充。(自 V2.0.11 起支持) + +#### 3.2.1 参数介绍 + +- **TIME_BOUND(可选)**:向后查看的时间阈值。如果当前空值的时间戳与后一个非空值的时间戳之间的间隔超过了此阈值,则不会进行填充。如果指定了该参数,系统会自动选取 `SELECT` 子句中第一个返回值类型为 `TIMESTAMP` 的列作为判断是否超过阈值的时间列。 +- **FILL_GROUP(可选)**:指定分组列,填充只会发生在同一分组内。如果指定了该参数,系统会自动选取 `SELECT` 子句中第一个返回值类型为 `TIMESTAMP` 的列作为组内排序的时间列。 +- **TIME_COLUMN(可选)**:若需手动指定用于判断时间阈值的 `TIMESTAMP` 列,可通过在 `TIME_COLUMN` 参数后指定数字(从 1 开始)来确定该列在 `SELECT` 列表中的位置。 + +**注意:** + +- 如果没有指定 `TIME_BOUND` 或 `FILL_GROUP` 参数,但指定了 `TIME_COLUMN`,系统将抛出语法错误。 +- 如果指定了 `TIME_BOUND` 或 `FILL_GROUP` 参数,但没有指定 `TIME_COLUMN`,且 `SELECT` 子句中不存在 `TIMESTAMP` 类型的列,系统将抛出异常。 +- 如果指定的 `TIME_COLUMN` 列不是 `TIMESTAMP` 类型,或指定的位置不在 `SELECT` 列表范围内,系统将抛出异常。 + +#### 3.2.2 示例 + +不使用任何填充方法: + +```sql +SELECT time, temperature, status + FROM table1 + WHERE time >= 2024-11-27 00:00:00 and time <= 2024-11-29 00:00:00 + AND plant_id='1001' and device_id='101'; +``` + +查询结果: + +```sql ++-----------------------------+-----------+------+ +| time|temperature|status| ++-----------------------------+-----------+------+ +|2024-11-27T16:38:00.000+08:00| null| true| +|2024-11-27T16:39:00.000+08:00| 85.0| null| +|2024-11-27T16:40:00.000+08:00| 85.0| null| +|2024-11-27T16:41:00.000+08:00| 85.0| null| +|2024-11-27T16:42:00.000+08:00| null| false| +|2024-11-27T16:43:00.000+08:00| null| false| +|2024-11-27T16:44:00.000+08:00| null| false| ++-----------------------------+-----------+------+ +Total line number = 7 +It costs 0.061s +``` + +使用 `NEXT` 填充方法(结果将使用后一个非空值填充 NULL 值): + +```sql +SELECT time, temperature, status + FROM table1 + WHERE time >= 2024-11-27 00:00:00 and time <= 2024-11-29 00:00:00 + AND plant_id='1001' and device_id='101' + FILL METHOD NEXT; +``` + +查询结果: + +```sql ++-----------------------------+-----------+------+ +| time|temperature|status| ++-----------------------------+-----------+------+ +|2024-11-27T16:38:00.000+08:00| 85.0| true| +|2024-11-27T16:39:00.000+08:00| 85.0| false| +|2024-11-27T16:40:00.000+08:00| 85.0| false| +|2024-11-27T16:41:00.000+08:00| 85.0| false| +|2024-11-27T16:42:00.000+08:00| null| false| +|2024-11-27T16:43:00.000+08:00| null| false| +|2024-11-27T16:44:00.000+08:00| null| false| ++-----------------------------+-----------+------+ +Total line number = 7 +It costs 0.033s +``` + +使用 `NEXT` 填充方法(指定时间阈值): + +```sql +-- 不指定时间列 +SELECT time, temperature, status + FROM table1 + WHERE time >= 2024-11-27 00:00:00 and time <= 2024-11-29 00:00:00 + AND plant_id='1001' and device_id='101' + FILL METHOD NEXT TIME_BOUND 1m; + +-- 手动指定时间列 +SELECT time, temperature, status + FROM table1 + WHERE time >= 2024-11-27 00:00:00 and time <= 2024-11-29 00:00:00 + AND plant_id='1001' and device_id='101' + FILL METHOD NEXT TIME_BOUND 1m TIME_COLUMN 1; +``` + +查询结果: + +```sql ++-----------------------------+-----------+------+ +| time|temperature|status| ++-----------------------------+-----------+------+ +|2024-11-27T16:38:00.000+08:00| 85.0| true| +|2024-11-27T16:39:00.000+08:00| 85.0| null| +|2024-11-27T16:40:00.000+08:00| 85.0| null| +|2024-11-27T16:41:00.000+08:00| 85.0| false| +|2024-11-27T16:42:00.000+08:00| null| false| +|2024-11-27T16:43:00.000+08:00| null| false| +|2024-11-27T16:44:00.000+08:00| null| false| ++-----------------------------+-----------+------+ +Total line number = 7 +It costs 0.047s +``` + +### 3.3 LINEAR 填充 对于查询结果集中的空值,用该列的前一个非空值和后一个非空值的线性插值填充。 -#### 3.2.1 线性填充规则: +#### 3.3.1 线性填充规则: - 如果之前都是空值,或者之后都是空值,则不进行填充。 - 如果列的数据类型是 boolean/string/blob/text,则不会进行填充,也不会抛出异常。 - 若没有指定时间列,默认选择 SELECT 子句中第一个数据类型为 TIMESTAMP 类型的列作为辅助时间列进行线性插值。如果不存在数据类型为TIMESTAMP的列,系统将抛出异常。 -#### 3.2.2 参数介绍: +#### 3.3.2 参数介绍: - TIME_COLUMN(可选):可以通过在`TIME_COLUMN`参数后指定数字(从1开始)来手动指定用于判断时间阈值的`TIMESTAMP`列,作为线性插值的辅助列,该数字代表原始表中`TIMESTAMP`列的具体位置。 注意:不强制要求线性插值的辅助列一定是 time 列,任何类型为 TIMESTAMP 的表达式都可以,不过因为线性插值只有在辅助列是升序或者降序的时候,才有意义,所以用户如果指定了其他的列,需要自行保证结果集是按照那一列升序或降序排列的。 -#### 3.2.3 示例 +#### 3.3.3 示例 ```sql SELECT time, temperature, status @@ -238,16 +350,16 @@ Total line number = 7 It costs 0.053s ``` -### 3.3 Constant 填充: +### 3.4 CONSTANT 填充 对于查询结果集中的空值,使用指定的常量进行填充。 -#### 3.3.1 常量填充规则: +#### 3.4.1 常量填充规则: - 若数据类型与输入的常量不匹配,IoTDB 不会填充查询结果,也不会抛出异常。 - 若插入的常量值超出了其数据类型所能表示的最大值,IoTDB 不会填充查询结果,也不会抛出异常。 -#### 3.3.2 示例 +#### 3.4.2 示例 使用`FLOAT`常量填充时,SQL 语句如下所示: @@ -307,7 +419,7 @@ It costs 0.073s ## 4. 高阶用法 -使用 `PREVIOUS` 和 `LINEAR` FILL 时,还支持额外的 `FILL_GROUP` 参数,来进行分组内填充。 +使用 `PREVIOUS`、`NEXT` 和 `LINEAR` FILL 时,还支持额外的 `FILL_GROUP` 参数,来进行分组内填充。 在使用 group by 子句 + fill 时,想在分组内进行填充,而不受其他分组的影响。 @@ -399,7 +511,7 @@ It costs 0.089s ## 5. 特别说明 -在使用 `LINEAR FILL` 或 `PREVIOUS FILL` 时,如果辅助时间列(用于确定填充逻辑的时间列)中存在 NULL 值,IoTDB 将遵循以下规则: +在使用 `LINEAR FILL`、`PREVIOUS FILL` 或 `NEXT FILL` 时,如果辅助时间列(用于确定填充逻辑的时间列)中存在 NULL 值,IoTDB 将遵循以下规则: - 不对辅助时间列为 NULL 的行进行填充。 - 这些行也不会参与到填充逻辑的计算中。 @@ -462,5 +574,5 @@ It costs 0.049s 填充结果详情: - 16:39、16:42、16:43 的 humidity 列,由于辅助列 arrival_time 为 NULL,所以不进行填充。 -- 16:40 的 humidity 列,由于辅助列 arrival_time 非 NULL ,为 `1970-01-01T08:00:00.003+08:00`且与前一个非 NULL 值 `1970-01-01T08:00:00.001+08:00`的时间差未超过 2ms,因此使用第一行 s1 的值 1 进行填充。 -- 16:41 的 humidity 列,尽管 arrival_time 非 NULL,但与前一个非 NULL 值的时间差超过 2ms,因此不进行填充。第七行同理。 \ No newline at end of file +- 16:40 的 humidity 列,由于辅助列 arrival_time 非 NULL ,为 `1970-01-01T08:00:00.003+08:00`且与前一个非 NULL 值 `1970-01-01T08:00:00.001+08:00`的时间差未超过 2ms,因此使用第一行 humidity 的值 35.1 进行填充。 +- 16:41 的 humidity 列,尽管 arrival_time 非 NULL,但与前一个非 NULL 值的时间差超过 2ms,因此不进行填充。第七行同理。 diff --git a/src/zh/UserGuide/Master/Table/SQL-Manual/GroupBy-Clause.md b/src/zh/UserGuide/Master/Table/SQL-Manual/GroupBy-Clause_apache.md similarity index 76% rename from src/zh/UserGuide/Master/Table/SQL-Manual/GroupBy-Clause.md rename to src/zh/UserGuide/Master/Table/SQL-Manual/GroupBy-Clause_apache.md index 814e76521..9263ef49e 100644 --- a/src/zh/UserGuide/Master/Table/SQL-Manual/GroupBy-Clause.md +++ b/src/zh/UserGuide/Master/Table/SQL-Manual/GroupBy-Clause_apache.md @@ -41,7 +41,7 @@ GROUP BY expression (',' expression)* ```sql SELECT concat(device_id, model_id), avg(temperature) FROM table1 - GROUP BY device_id, model_id; -- 合法 + GROUP BY device_id, model_id; ``` 执行结果如下: @@ -66,7 +66,7 @@ It costs 0.094s ```sql SELECT device_id, temperature FROM table1 - GROUP BY device_id;-- 不合法 + GROUP BY device_id; ``` 执行结果如下: @@ -81,7 +81,7 @@ Msg: org.apache.iotdb.jdbc.IoTDBSQLException: 701: ```sql SELECT device_id, avg(temperature) FROM table1 - GROUP BY model; -- 不合法 + GROUP BY model; ``` 执行结果如下: @@ -97,7 +97,7 @@ Msg: org.apache.iotdb.jdbc.IoTDBSQLException: 701: ```sql SELECT COUNT(*), avg(temperature) - FROM table1; -- 合法 + FROM table1; ``` 执行结果如下: @@ -115,7 +115,7 @@ It costs 0.094s 不合法示例: ```sql -SELECT humidity, avg(temperature) FROM table1; -- 不合法 +SELECT humidity, avg(temperature) FROM table1; ``` 执行结果如下: @@ -150,7 +150,7 @@ Total line number = 5 It costs 0.092s ``` -- 不支持在 group by 子句中使用 select item 的别名。以下 SQL 将抛出错误,可以使用上述 SQL 代替。 +- 在 V2.0.11 之前的版本中,不支持在 group by 子句中使用 select item 的别名,需要使用完整的表达式(或 select item 的常量序号)代替,如下 SQL 所示: ```sql SELECT date_bin(1h, time) AS hour_time, device_id, avg(temperature) @@ -175,6 +175,64 @@ Total line number = 5 It costs 0.092s ``` +- 自 V2.0.11 起,GROUP BY 子句支持引用 SELECT 子句中显式定义的别名。 + - 该能力仅适用于直接引用别名本身的场景;带表名前缀的名称(例如 GROUP BY table1.hour_time)不按 SELECT 别名展开,仍按普通表达式解析。 + - GROUP BY 中引用的名称会优先解析为当前查询的输入列;只有无法解析为输入列时,才会继续解析为 SELECT 别名。如果 SELECT 列表中存在多个同名别名,引用该别名时会抛出歧义错误。 + - GROUP BY 别名解析后,仍然执行已有的 GROUP BY 校验规则。例如,分组键不能包含聚合函数、窗口函数或 grouping 函数。 + +合法示例: + +```sql +SELECT date_bin(1h, time) AS hour_time, device_id, avg(temperature) + FROM table1 + WHERE time >= 2024-11-27 00:00:00 and time <= 2024-11-29 00:00:00 + GROUP BY hour_time, device_id; +``` + +执行结果如下: + +```sql ++-----------------------------+---------+-----+ +| hour_time|device_id|_col2| ++-----------------------------+---------+-----+ +|2024-11-28T08:00:00.000+08:00| 100| 85.0| +|2024-11-28T09:00:00.000+08:00| 100| null| +|2024-11-28T10:00:00.000+08:00| 100| 85.0| +|2024-11-28T11:00:00.000+08:00| 100| 88.0| +|2024-11-27T16:00:00.000+08:00| 101| 85.0| ++-----------------------------+---------+-----+ +Total line number = 5 +It costs 0.228s +``` + +不合法示例1:同一语句中包含同名别名 + +```sql +SELECT temperature AS value, humidity AS value + FROM table1 + GROUP BY value; +``` + +执行结果如下: + +```sql +Msg: org.apache.iotdb.jdbc.IoTDBSQLException: 701: Column alias 'value' is ambiguous at positions 1, 2 +``` + +不合法示例2:分组键包含聚合函数 + +```sql +SELECT AVG(temperature) AS avg_temperature + FROM table1 + GROUP BY avg_temperature; +``` + +执行结果如下: + +```sql +Msg: org.apache.iotdb.jdbc.IoTDBSQLException: 701: GROUP BY clause cannot contain aggregations, window functions or grouping operations: [AVG(temperature)] +``` + - 只有 COUNT 函数可以与星号(*)一起使用,用于计算表中的总行数。其他聚合函数与`*`一起使用,将抛出错误。 ```sql @@ -209,6 +267,16 @@ SELECT date_bin(1h, time) AS hour_time, AVG(temperature) AS avg_temperature GROUP BY 1; ``` +自 V2.0.11 起,GROUP BY 项可以直接引用 SELECT 子句中显式定义的别名,因此上述 SQL 可以写为 + +```sql +SELECT date_bin(1h, time) AS hour_time, AVG(temperature) AS avg_temperature + FROM table1 + WHERE time >= 2024-11-27 00:00:00 and time <= 2024-11-30 00:00:00 + AND device_id='101' + GROUP BY hour_time; +``` + 执行结果如下: ```sql @@ -361,4 +429,4 @@ HAVING COUNT(*) > 1; +--------+---------+ Total line number = 2 It costs 0.073s -``` \ No newline at end of file +``` diff --git a/src/zh/UserGuide/latest-Table/SQL-Manual/OrderBy-Clause.md b/src/zh/UserGuide/Master/Table/SQL-Manual/OrderBy-Clause_apache.md similarity index 87% rename from src/zh/UserGuide/latest-Table/SQL-Manual/OrderBy-Clause.md rename to src/zh/UserGuide/Master/Table/SQL-Manual/OrderBy-Clause_apache.md index 66cf55068..8ab06f5d5 100644 --- a/src/zh/UserGuide/latest-Table/SQL-Manual/OrderBy-Clause.md +++ b/src/zh/UserGuide/Master/Table/SQL-Manual/OrderBy-Clause_apache.md @@ -37,6 +37,7 @@ sortItem - 提供了对 NULL 值排序位置的控制,允许用户指定 NULL 值是排在结果的开头(NULLS FIRST)还是结尾(NULLS LAST)。 - 默认情况下, 将采用 ASC NULLS LAST排序,即值按升序排序,空值放在最后。可以通过手动指定其他参数更改默认排序顺序。 - ORDER BY 子句的执行顺序排在 LIMIT 或 OFFSET 子句之前。 +- 自 V2.0.11 起,ORDER BY 子句支持引用 SELECT 子句中显式定义的别名。ORDER BY 中直接引用一个名称时,会优先解析为 SELECT 输出别名;如果 SELECT 列表中存在多个同名别名,引用该别名时会抛出歧义错误。 ## 2. 示例数据 @@ -132,4 +133,33 @@ SELECT * +-----------------------------+------+--------+---------+--------+-----------+-----------+--------+------+-----------------------------+ Total line number = 10 It costs 0.069s +``` + +#### 示例 4:按时间桶聚合并按别名排序(通过 SELECT 别名) + +```sql +SELECT date_bin(1h, time) AS hour_time, AVG(temperature) AS avg_temperature + FROM table1 + WHERE time >= 2024-11-27 00:00:00 and time <= 2024-11-30 00:00:00 + GROUP BY hour_time + ORDER BY hour_time; +``` + +执行结果如下: + +```sql ++-----------------------------+---------------+ +| hour_time|avg_temperature| ++-----------------------------+---------------+ +|2024-11-27T16:00:00.000+08:00| 85.0| +|2024-11-28T08:00:00.000+08:00| 85.0| +|2024-11-28T09:00:00.000+08:00| null| +|2024-11-28T10:00:00.000+08:00| 85.0| +|2024-11-28T11:00:00.000+08:00| 88.0| +|2024-11-29T10:00:00.000+08:00| 85.0| +|2024-11-29T11:00:00.000+08:00| null| +|2024-11-29T18:00:00.000+08:00| 90.0| ++-----------------------------+---------------+ +Total line number = 8 +It costs 0.079s ``` \ No newline at end of file diff --git a/src/zh/UserGuide/Master/Table/SQL-Manual/Select-Clause_apache.md b/src/zh/UserGuide/Master/Table/SQL-Manual/Select-Clause_apache.md index c1aecba1b..2c607cfbb 100644 --- a/src/zh/UserGuide/Master/Table/SQL-Manual/Select-Clause_apache.md +++ b/src/zh/UserGuide/Master/Table/SQL-Manual/Select-Clause_apache.md @@ -113,7 +113,7 @@ It costs 0.653s #### 3.1.2 聚合函数 -聚合函数将多行数据汇总为单个值。当 SELECT 子句中存在聚合函数时,查询将被视为聚合查询。在聚合查询中,所有表达式必须是聚合函数的一部分或由[GROUP BY子句](../SQL-Manual/GroupBy-Clause.md)指定的分组的一部分。 +聚合函数将多行数据汇总为单个值。当 SELECT 子句中存在聚合函数时,查询将被视为聚合查询。在聚合查询中,所有表达式必须是聚合函数的一部分或由[GROUP BY子句](../SQL-Manual/GroupBy-Clause_apache.md)指定的分组的一部分。 示例1:返回地址表中的总行数: diff --git a/src/zh/UserGuide/Master/Table/SQL-Manual/overview_apache.md b/src/zh/UserGuide/Master/Table/SQL-Manual/overview_apache.md index 4f8ca7579..81a373677 100644 --- a/src/zh/UserGuide/Master/Table/SQL-Manual/overview_apache.md +++ b/src/zh/UserGuide/Master/Table/SQL-Manual/overview_apache.md @@ -40,10 +40,10 @@ IoTDB 查询语法提供以下子句: - SELECT 子句:查询结果应包含的列。详细语法见:[SELECT子句](../SQL-Manual/Select-Clause_apache.md) - FROM 子句:指出查询的数据源,可以是单个表、多个通过 `JOIN` 子句连接的表,或者是一个子查询。详细语法见:[FROM & JOIN 子句](../SQL-Manual/From-Join-Clause.md) - WHERE 子句:用于过滤数据,只选择满足特定条件的数据行。这个子句在逻辑上紧跟在 FROM 子句之后执行。详细语法见:[WHERE 子句](../SQL-Manual/Where-Clause.md) -- GROUP BY 子句:当需要对数据进行聚合时使用,指定了用于分组的列。详细语法见:[GROUP BY 子句](../SQL-Manual/GroupBy-Clause.md) +- GROUP BY 子句:当需要对数据进行聚合时使用,指定了用于分组的列。详细语法见:[GROUP BY 子句](../SQL-Manual/GroupBy-Clause_apache.md) - HAVING 子句:在 GROUP BY 子句之后使用,用于对已经分组的数据进行过滤。与 WHERE 子句类似,但 HAVING 子句在分组后执行。详细语法见:[HAVING 子句](../SQL-Manual/Having-Clause.md) -- FILL 子句:用于处理查询结果中的空值,用户可以使用 FILL 子句来指定数据缺失时的填充模式(如前一个非空值或线性插值)来填充 null 值,以便于数据可视化和分析。 详细语法见:[FILL 子句](../SQL-Manual/Fill-Clause.md) -- ORDER BY 子句:对查询结果进行排序,可以指定升序(ASC)或降序(DESC),以及 NULL 值的处理方式(NULLS FIRST 或 NULLS LAST)。详细语法见:[ORDER BY 子句](../SQL-Manual/OrderBy-Clause.md) +- FILL 子句:用于处理查询结果中的空值,用户可以使用 FILL 子句来指定数据缺失时的填充模式(如前一个非空值或线性插值)来填充 null 值,以便于数据可视化和分析。 详细语法见:[FILL 子句](../SQL-Manual/Fill-Clause_apache.md) +- ORDER BY 子句:对查询结果进行排序,可以指定升序(ASC)或降序(DESC),以及 NULL 值的处理方式(NULLS FIRST 或 NULLS LAST)。详细语法见:[ORDER BY 子句](../SQL-Manual/OrderBy-Clause_apache.md) - OFFSET 子句:用于指定查询结果的起始位置,即跳过前 OFFSET 行。与 LIMIT 子句配合使用。详细语法见:[LIMIT 和 OFFSET 子句](../SQL-Manual/Limit-Offset-Clause.md) - LIMIT 子句:限制查询结果的行数,通常与 OFFSET 子句一起使用以实现分页功能。详细语法见:[LIMIT 和 OFFSET 子句](../SQL-Manual/Limit-Offset-Clause.md) diff --git a/src/zh/UserGuide/latest-Table/Basic-Concept/Query-Data_apache.md b/src/zh/UserGuide/latest-Table/Basic-Concept/Query-Data_apache.md index f43389f74..20f9fe61f 100644 --- a/src/zh/UserGuide/latest-Table/Basic-Concept/Query-Data_apache.md +++ b/src/zh/UserGuide/latest-Table/Basic-Concept/Query-Data_apache.md @@ -40,10 +40,10 @@ IoTDB 查询语法提供以下子句: - SELECT 子句:查询结果应包含的列。详细语法见:[SELECT子句](../SQL-Manual/Select-Clause_apache.md) - FROM 子句:指出查询的数据源,可以是单个表、多个通过 `JOIN` 子句连接的表,或者是一个子查询。详细语法见:[FROM & JOIN 子句](../SQL-Manual/From-Join-Clause.md) - WHERE 子句:用于过滤数据,只选择满足特定条件的数据行。这个子句在逻辑上紧跟在 FROM 子句之后执行。详细语法见:[WHERE 子句](../SQL-Manual/Where-Clause.md) -- GROUP BY 子句:当需要对数据进行聚合时使用,指定了用于分组的列。详细语法见:[GROUP BY 子句](../SQL-Manual/GroupBy-Clause.md) +- GROUP BY 子句:当需要对数据进行聚合时使用,指定了用于分组的列。详细语法见:[GROUP BY 子句](../SQL-Manual/GroupBy-Clause_apache.md) - HAVING 子句:在 GROUP BY 子句之后使用,用于对已经分组的数据进行过滤。与 WHERE 子句类似,但 HAVING 子句在分组后执行。详细语法见:[HAVING 子句](../SQL-Manual/Having-Clause.md) -- FILL 子句:用于处理查询结果中的空值,用户可以使用 FILL 子句来指定数据缺失时的填充模式(如前一个非空值或线性插值)来填充 null 值,以便于数据可视化和分析。 详细语法见:[FILL 子句](../SQL-Manual/Fill-Clause.md) -- ORDER BY 子句:对查询结果进行排序,可以指定升序(ASC)或降序(DESC),以及 NULL 值的处理方式(NULLS FIRST 或 NULLS LAST)。详细语法见:[ORDER BY 子句](../SQL-Manual/OrderBy-Clause.md) +- FILL 子句:用于处理查询结果中的空值,用户可以使用 FILL 子句来指定数据缺失时的填充模式(如前一个非空值或线性插值)来填充 null 值,以便于数据可视化和分析。 详细语法见:[FILL 子句](../SQL-Manual/Fill-Clause_apache.md) +- ORDER BY 子句:对查询结果进行排序,可以指定升序(ASC)或降序(DESC),以及 NULL 值的处理方式(NULLS FIRST 或 NULLS LAST)。详细语法见:[ORDER BY 子句](../SQL-Manual/OrderBy-Clause_apache.md) - OFFSET 子句:用于指定查询结果的起始位置,即跳过前 OFFSET 行。与 LIMIT 子句配合使用。详细语法见:[LIMIT 和 OFFSET 子句](../SQL-Manual/Limit-Offset-Clause.md) - LIMIT 子句:限制查询结果的行数,通常与 OFFSET 子句一起使用以实现分页功能。详细语法见:[LIMIT 和 OFFSET 子句](../SQL-Manual/Limit-Offset-Clause.md) diff --git a/src/zh/UserGuide/latest-Table/SQL-Manual/Fill-Clause.md b/src/zh/UserGuide/latest-Table/SQL-Manual/Fill-Clause_apache.md similarity index 73% rename from src/zh/UserGuide/latest-Table/SQL-Manual/Fill-Clause.md rename to src/zh/UserGuide/latest-Table/SQL-Manual/Fill-Clause_apache.md index 1d89c3fc7..6ddf69686 100644 --- a/src/zh/UserGuide/latest-Table/SQL-Manual/Fill-Clause.md +++ b/src/zh/UserGuide/latest-Table/SQL-Manual/Fill-Clause_apache.md @@ -37,6 +37,7 @@ fillClause fillMethod : LINEAR timeColumnClause? fillGroupClause? #linearFill | PREVIOUS timeBoundClause? timeColumnClause? fillGroupClause? #previousFill + | NEXT timeBoundClause? timeColumnClause? fillGroupClause? #nextFill | CONSTANT literalExpression #valueFill ; @@ -62,28 +63,30 @@ intervalField ### 2.1 填充方式 -IoTDB 支持以下三种空值填充方式: +IoTDB 支持以下四种空值填充方式: -1. **`PREVIOUS`填充**:使用该列前一个非空值进行填充,V2.0.8 版本起仅该方式支持支持 OBJECT 类型。 -2. **`LINEAR`填充**:使用该列前一个非空值和下一个非空值的线性插值进行填充。 -3. **`Constant`填充**:使用指定的常量值进行填充。 +1. **`PREVIOUS` 填充**:使用该列前一个非空值进行填充。 +2. **`NEXT` 填充**:使用该列后一个非空值进行填充。 +3. **`LINEAR` 填充**:使用该列前一个非空值和下一个非空值的线性插值进行填充。 +4. **`CONSTANT` 填充**:使用指定的常量值进行填充。 只能指定一种填充方法,且该方法会作用于结果集的全部列。 ### 2.2 数据类型与支持的填充方法 -| Data Type | Previous | Linear | Constant | -| :-------- | :------- | :----- | :------- | -| boolean | √ | - | √ | -| int32 | √ | √ | √ | -| int64 | √ | √ | √ | -| float | √ | √ | √ | -| double | √ | √ | √ | -| text | √ | - | √ | -| string | √ | - | √ | -| blob | √ | - | √ | -| timestamp | √ | √ | √ | -| date | √ | √ | √ | +| Data Type | Previous | Next | Linear | Constant | +| :-------- | :------- | :--- | :----- | :------- | +| boolean | √ | √ | - | √ | +| int32 | √ | √ | √ | √ | +| int64 | √ | √ | √ | √ | +| float | √ | √ | √ | √ | +| double | √ | √ | √ | √ | +| text | √ | √ | - | √ | +| string | √ | √ | - | √ | +| blob | √ | √ | - | √ | +| timestamp | √ | √ | √ | √ | +| date | √ | √ | √ | √ | +| OBJECT | √ | √ | - | - | 注意:对于数据类型不支持指定填充方法的列,既不进行填充,也不抛出异常,只是保持原样。 @@ -173,7 +176,7 @@ SELECT time, temperature, status FROM table1 WHERE time >= 2024-11-27 00:00:00 and time <= 2024-11-29 00:00:00 AND plant_id='1001' and device_id='101' - FILL METHOD PREVIOUS 1m TIME_COLUMN 1; + FILL METHOD PREVIOUS TIME_BOUND 1m TIME_COLUMN 1; ``` 查询结果: @@ -194,23 +197,132 @@ Total line number = 7 It costs 0.075s ``` -### 3.2 LINEAR 填充 +### 3.2 NEXT 填充 + +对于查询结果集中的空值,使用该列的后一个非空值进行填充。(自 V2.0.11 起支持) + +#### 3.2.1 参数介绍 + +- **TIME_BOUND(可选)**:向后查看的时间阈值。如果当前空值的时间戳与后一个非空值的时间戳之间的间隔超过了此阈值,则不会进行填充。如果指定了该参数,系统会自动选取 `SELECT` 子句中第一个返回值类型为 `TIMESTAMP` 的列作为判断是否超过阈值的时间列。 +- **FILL_GROUP(可选)**:指定分组列,填充只会发生在同一分组内。如果指定了该参数,系统会自动选取 `SELECT` 子句中第一个返回值类型为 `TIMESTAMP` 的列作为组内排序的时间列。 +- **TIME_COLUMN(可选)**:若需手动指定用于判断时间阈值的 `TIMESTAMP` 列,可通过在 `TIME_COLUMN` 参数后指定数字(从 1 开始)来确定该列在 `SELECT` 列表中的位置。 + +**注意:** + +- 如果没有指定 `TIME_BOUND` 或 `FILL_GROUP` 参数,但指定了 `TIME_COLUMN`,系统将抛出语法错误。 +- 如果指定了 `TIME_BOUND` 或 `FILL_GROUP` 参数,但没有指定 `TIME_COLUMN`,且 `SELECT` 子句中不存在 `TIMESTAMP` 类型的列,系统将抛出异常。 +- 如果指定的 `TIME_COLUMN` 列不是 `TIMESTAMP` 类型,或指定的位置不在 `SELECT` 列表范围内,系统将抛出异常。 + +#### 3.2.2 示例 + +不使用任何填充方法: + +```sql +SELECT time, temperature, status + FROM table1 + WHERE time >= 2024-11-27 00:00:00 and time <= 2024-11-29 00:00:00 + AND plant_id='1001' and device_id='101'; +``` + +查询结果: + +```sql ++-----------------------------+-----------+------+ +| time|temperature|status| ++-----------------------------+-----------+------+ +|2024-11-27T16:38:00.000+08:00| null| true| +|2024-11-27T16:39:00.000+08:00| 85.0| null| +|2024-11-27T16:40:00.000+08:00| 85.0| null| +|2024-11-27T16:41:00.000+08:00| 85.0| null| +|2024-11-27T16:42:00.000+08:00| null| false| +|2024-11-27T16:43:00.000+08:00| null| false| +|2024-11-27T16:44:00.000+08:00| null| false| ++-----------------------------+-----------+------+ +Total line number = 7 +It costs 0.061s +``` + +使用 `NEXT` 填充方法(结果将使用后一个非空值填充 NULL 值): + +```sql +SELECT time, temperature, status + FROM table1 + WHERE time >= 2024-11-27 00:00:00 and time <= 2024-11-29 00:00:00 + AND plant_id='1001' and device_id='101' + FILL METHOD NEXT; +``` + +查询结果: + +```sql ++-----------------------------+-----------+------+ +| time|temperature|status| ++-----------------------------+-----------+------+ +|2024-11-27T16:38:00.000+08:00| 85.0| true| +|2024-11-27T16:39:00.000+08:00| 85.0| false| +|2024-11-27T16:40:00.000+08:00| 85.0| false| +|2024-11-27T16:41:00.000+08:00| 85.0| false| +|2024-11-27T16:42:00.000+08:00| null| false| +|2024-11-27T16:43:00.000+08:00| null| false| +|2024-11-27T16:44:00.000+08:00| null| false| ++-----------------------------+-----------+------+ +Total line number = 7 +It costs 0.033s +``` + +使用 `NEXT` 填充方法(指定时间阈值): + +```sql +-- 不指定时间列 +SELECT time, temperature, status + FROM table1 + WHERE time >= 2024-11-27 00:00:00 and time <= 2024-11-29 00:00:00 + AND plant_id='1001' and device_id='101' + FILL METHOD NEXT TIME_BOUND 1m; + +-- 手动指定时间列 +SELECT time, temperature, status + FROM table1 + WHERE time >= 2024-11-27 00:00:00 and time <= 2024-11-29 00:00:00 + AND plant_id='1001' and device_id='101' + FILL METHOD NEXT TIME_BOUND 1m TIME_COLUMN 1; +``` + +查询结果: + +```sql ++-----------------------------+-----------+------+ +| time|temperature|status| ++-----------------------------+-----------+------+ +|2024-11-27T16:38:00.000+08:00| 85.0| true| +|2024-11-27T16:39:00.000+08:00| 85.0| null| +|2024-11-27T16:40:00.000+08:00| 85.0| null| +|2024-11-27T16:41:00.000+08:00| 85.0| false| +|2024-11-27T16:42:00.000+08:00| null| false| +|2024-11-27T16:43:00.000+08:00| null| false| +|2024-11-27T16:44:00.000+08:00| null| false| ++-----------------------------+-----------+------+ +Total line number = 7 +It costs 0.047s +``` + +### 3.3 LINEAR 填充 对于查询结果集中的空值,用该列的前一个非空值和后一个非空值的线性插值填充。 -#### 3.2.1 线性填充规则: +#### 3.3.1 线性填充规则: - 如果之前都是空值,或者之后都是空值,则不进行填充。 - 如果列的数据类型是 boolean/string/blob/text,则不会进行填充,也不会抛出异常。 - 若没有指定时间列,默认选择 SELECT 子句中第一个数据类型为 TIMESTAMP 类型的列作为辅助时间列进行线性插值。如果不存在数据类型为TIMESTAMP的列,系统将抛出异常。 -#### 3.2.2 参数介绍: +#### 3.3.2 参数介绍: - TIME_COLUMN(可选):可以通过在`TIME_COLUMN`参数后指定数字(从1开始)来手动指定用于判断时间阈值的`TIMESTAMP`列,作为线性插值的辅助列,该数字代表原始表中`TIMESTAMP`列的具体位置。 注意:不强制要求线性插值的辅助列一定是 time 列,任何类型为 TIMESTAMP 的表达式都可以,不过因为线性插值只有在辅助列是升序或者降序的时候,才有意义,所以用户如果指定了其他的列,需要自行保证结果集是按照那一列升序或降序排列的。 -#### 3.2.3 示例 +#### 3.3.3 示例 ```sql SELECT time, temperature, status @@ -238,16 +350,16 @@ Total line number = 7 It costs 0.053s ``` -### 3.3 Constant 填充: +### 3.4 CONSTANT 填充 对于查询结果集中的空值,使用指定的常量进行填充。 -#### 3.3.1 常量填充规则: +#### 3.4.1 常量填充规则: - 若数据类型与输入的常量不匹配,IoTDB 不会填充查询结果,也不会抛出异常。 - 若插入的常量值超出了其数据类型所能表示的最大值,IoTDB 不会填充查询结果,也不会抛出异常。 -#### 3.3.2 示例 +#### 3.4.2 示例 使用`FLOAT`常量填充时,SQL 语句如下所示: @@ -307,7 +419,7 @@ It costs 0.073s ## 4. 高阶用法 -使用 `PREVIOUS` 和 `LINEAR` FILL 时,还支持额外的 `FILL_GROUP` 参数,来进行分组内填充。 +使用 `PREVIOUS`、`NEXT` 和 `LINEAR` FILL 时,还支持额外的 `FILL_GROUP` 参数,来进行分组内填充。 在使用 group by 子句 + fill 时,想在分组内进行填充,而不受其他分组的影响。 @@ -399,7 +511,7 @@ It costs 0.089s ## 5. 特别说明 -在使用 `LINEAR FILL` 或 `PREVIOUS FILL` 时,如果辅助时间列(用于确定填充逻辑的时间列)中存在 NULL 值,IoTDB 将遵循以下规则: +在使用 `LINEAR FILL`、`PREVIOUS FILL` 或 `NEXT FILL` 时,如果辅助时间列(用于确定填充逻辑的时间列)中存在 NULL 值,IoTDB 将遵循以下规则: - 不对辅助时间列为 NULL 的行进行填充。 - 这些行也不会参与到填充逻辑的计算中。 @@ -462,5 +574,5 @@ It costs 0.049s 填充结果详情: - 16:39、16:42、16:43 的 humidity 列,由于辅助列 arrival_time 为 NULL,所以不进行填充。 -- 16:40 的 humidity 列,由于辅助列 arrival_time 非 NULL ,为 `1970-01-01T08:00:00.003+08:00`且与前一个非 NULL 值 `1970-01-01T08:00:00.001+08:00`的时间差未超过 2ms,因此使用第一行 s1 的值 1 进行填充。 -- 16:41 的 humidity 列,尽管 arrival_time 非 NULL,但与前一个非 NULL 值的时间差超过 2ms,因此不进行填充。第七行同理。 \ No newline at end of file +- 16:40 的 humidity 列,由于辅助列 arrival_time 非 NULL ,为 `1970-01-01T08:00:00.003+08:00`且与前一个非 NULL 值 `1970-01-01T08:00:00.001+08:00`的时间差未超过 2ms,因此使用第一行 humidity 的值 35.1 进行填充。 +- 16:41 的 humidity 列,尽管 arrival_time 非 NULL,但与前一个非 NULL 值的时间差超过 2ms,因此不进行填充。第七行同理。 diff --git a/src/zh/UserGuide/latest-Table/SQL-Manual/GroupBy-Clause.md b/src/zh/UserGuide/latest-Table/SQL-Manual/GroupBy-Clause_apache.md similarity index 76% rename from src/zh/UserGuide/latest-Table/SQL-Manual/GroupBy-Clause.md rename to src/zh/UserGuide/latest-Table/SQL-Manual/GroupBy-Clause_apache.md index 814e76521..9263ef49e 100644 --- a/src/zh/UserGuide/latest-Table/SQL-Manual/GroupBy-Clause.md +++ b/src/zh/UserGuide/latest-Table/SQL-Manual/GroupBy-Clause_apache.md @@ -41,7 +41,7 @@ GROUP BY expression (',' expression)* ```sql SELECT concat(device_id, model_id), avg(temperature) FROM table1 - GROUP BY device_id, model_id; -- 合法 + GROUP BY device_id, model_id; ``` 执行结果如下: @@ -66,7 +66,7 @@ It costs 0.094s ```sql SELECT device_id, temperature FROM table1 - GROUP BY device_id;-- 不合法 + GROUP BY device_id; ``` 执行结果如下: @@ -81,7 +81,7 @@ Msg: org.apache.iotdb.jdbc.IoTDBSQLException: 701: ```sql SELECT device_id, avg(temperature) FROM table1 - GROUP BY model; -- 不合法 + GROUP BY model; ``` 执行结果如下: @@ -97,7 +97,7 @@ Msg: org.apache.iotdb.jdbc.IoTDBSQLException: 701: ```sql SELECT COUNT(*), avg(temperature) - FROM table1; -- 合法 + FROM table1; ``` 执行结果如下: @@ -115,7 +115,7 @@ It costs 0.094s 不合法示例: ```sql -SELECT humidity, avg(temperature) FROM table1; -- 不合法 +SELECT humidity, avg(temperature) FROM table1; ``` 执行结果如下: @@ -150,7 +150,7 @@ Total line number = 5 It costs 0.092s ``` -- 不支持在 group by 子句中使用 select item 的别名。以下 SQL 将抛出错误,可以使用上述 SQL 代替。 +- 在 V2.0.11 之前的版本中,不支持在 group by 子句中使用 select item 的别名,需要使用完整的表达式(或 select item 的常量序号)代替,如下 SQL 所示: ```sql SELECT date_bin(1h, time) AS hour_time, device_id, avg(temperature) @@ -175,6 +175,64 @@ Total line number = 5 It costs 0.092s ``` +- 自 V2.0.11 起,GROUP BY 子句支持引用 SELECT 子句中显式定义的别名。 + - 该能力仅适用于直接引用别名本身的场景;带表名前缀的名称(例如 GROUP BY table1.hour_time)不按 SELECT 别名展开,仍按普通表达式解析。 + - GROUP BY 中引用的名称会优先解析为当前查询的输入列;只有无法解析为输入列时,才会继续解析为 SELECT 别名。如果 SELECT 列表中存在多个同名别名,引用该别名时会抛出歧义错误。 + - GROUP BY 别名解析后,仍然执行已有的 GROUP BY 校验规则。例如,分组键不能包含聚合函数、窗口函数或 grouping 函数。 + +合法示例: + +```sql +SELECT date_bin(1h, time) AS hour_time, device_id, avg(temperature) + FROM table1 + WHERE time >= 2024-11-27 00:00:00 and time <= 2024-11-29 00:00:00 + GROUP BY hour_time, device_id; +``` + +执行结果如下: + +```sql ++-----------------------------+---------+-----+ +| hour_time|device_id|_col2| ++-----------------------------+---------+-----+ +|2024-11-28T08:00:00.000+08:00| 100| 85.0| +|2024-11-28T09:00:00.000+08:00| 100| null| +|2024-11-28T10:00:00.000+08:00| 100| 85.0| +|2024-11-28T11:00:00.000+08:00| 100| 88.0| +|2024-11-27T16:00:00.000+08:00| 101| 85.0| ++-----------------------------+---------+-----+ +Total line number = 5 +It costs 0.228s +``` + +不合法示例1:同一语句中包含同名别名 + +```sql +SELECT temperature AS value, humidity AS value + FROM table1 + GROUP BY value; +``` + +执行结果如下: + +```sql +Msg: org.apache.iotdb.jdbc.IoTDBSQLException: 701: Column alias 'value' is ambiguous at positions 1, 2 +``` + +不合法示例2:分组键包含聚合函数 + +```sql +SELECT AVG(temperature) AS avg_temperature + FROM table1 + GROUP BY avg_temperature; +``` + +执行结果如下: + +```sql +Msg: org.apache.iotdb.jdbc.IoTDBSQLException: 701: GROUP BY clause cannot contain aggregations, window functions or grouping operations: [AVG(temperature)] +``` + - 只有 COUNT 函数可以与星号(*)一起使用,用于计算表中的总行数。其他聚合函数与`*`一起使用,将抛出错误。 ```sql @@ -209,6 +267,16 @@ SELECT date_bin(1h, time) AS hour_time, AVG(temperature) AS avg_temperature GROUP BY 1; ``` +自 V2.0.11 起,GROUP BY 项可以直接引用 SELECT 子句中显式定义的别名,因此上述 SQL 可以写为 + +```sql +SELECT date_bin(1h, time) AS hour_time, AVG(temperature) AS avg_temperature + FROM table1 + WHERE time >= 2024-11-27 00:00:00 and time <= 2024-11-30 00:00:00 + AND device_id='101' + GROUP BY hour_time; +``` + 执行结果如下: ```sql @@ -361,4 +429,4 @@ HAVING COUNT(*) > 1; +--------+---------+ Total line number = 2 It costs 0.073s -``` \ No newline at end of file +``` diff --git a/src/zh/UserGuide/Master/Table/SQL-Manual/OrderBy-Clause.md b/src/zh/UserGuide/latest-Table/SQL-Manual/OrderBy-Clause_apache.md similarity index 87% rename from src/zh/UserGuide/Master/Table/SQL-Manual/OrderBy-Clause.md rename to src/zh/UserGuide/latest-Table/SQL-Manual/OrderBy-Clause_apache.md index 66cf55068..8ab06f5d5 100644 --- a/src/zh/UserGuide/Master/Table/SQL-Manual/OrderBy-Clause.md +++ b/src/zh/UserGuide/latest-Table/SQL-Manual/OrderBy-Clause_apache.md @@ -37,6 +37,7 @@ sortItem - 提供了对 NULL 值排序位置的控制,允许用户指定 NULL 值是排在结果的开头(NULLS FIRST)还是结尾(NULLS LAST)。 - 默认情况下, 将采用 ASC NULLS LAST排序,即值按升序排序,空值放在最后。可以通过手动指定其他参数更改默认排序顺序。 - ORDER BY 子句的执行顺序排在 LIMIT 或 OFFSET 子句之前。 +- 自 V2.0.11 起,ORDER BY 子句支持引用 SELECT 子句中显式定义的别名。ORDER BY 中直接引用一个名称时,会优先解析为 SELECT 输出别名;如果 SELECT 列表中存在多个同名别名,引用该别名时会抛出歧义错误。 ## 2. 示例数据 @@ -132,4 +133,33 @@ SELECT * +-----------------------------+------+--------+---------+--------+-----------+-----------+--------+------+-----------------------------+ Total line number = 10 It costs 0.069s +``` + +#### 示例 4:按时间桶聚合并按别名排序(通过 SELECT 别名) + +```sql +SELECT date_bin(1h, time) AS hour_time, AVG(temperature) AS avg_temperature + FROM table1 + WHERE time >= 2024-11-27 00:00:00 and time <= 2024-11-30 00:00:00 + GROUP BY hour_time + ORDER BY hour_time; +``` + +执行结果如下: + +```sql ++-----------------------------+---------------+ +| hour_time|avg_temperature| ++-----------------------------+---------------+ +|2024-11-27T16:00:00.000+08:00| 85.0| +|2024-11-28T08:00:00.000+08:00| 85.0| +|2024-11-28T09:00:00.000+08:00| null| +|2024-11-28T10:00:00.000+08:00| 85.0| +|2024-11-28T11:00:00.000+08:00| 88.0| +|2024-11-29T10:00:00.000+08:00| 85.0| +|2024-11-29T11:00:00.000+08:00| null| +|2024-11-29T18:00:00.000+08:00| 90.0| ++-----------------------------+---------------+ +Total line number = 8 +It costs 0.079s ``` \ No newline at end of file diff --git a/src/zh/UserGuide/latest-Table/SQL-Manual/Select-Clause_apache.md b/src/zh/UserGuide/latest-Table/SQL-Manual/Select-Clause_apache.md index c1aecba1b..2c607cfbb 100644 --- a/src/zh/UserGuide/latest-Table/SQL-Manual/Select-Clause_apache.md +++ b/src/zh/UserGuide/latest-Table/SQL-Manual/Select-Clause_apache.md @@ -113,7 +113,7 @@ It costs 0.653s #### 3.1.2 聚合函数 -聚合函数将多行数据汇总为单个值。当 SELECT 子句中存在聚合函数时,查询将被视为聚合查询。在聚合查询中,所有表达式必须是聚合函数的一部分或由[GROUP BY子句](../SQL-Manual/GroupBy-Clause.md)指定的分组的一部分。 +聚合函数将多行数据汇总为单个值。当 SELECT 子句中存在聚合函数时,查询将被视为聚合查询。在聚合查询中,所有表达式必须是聚合函数的一部分或由[GROUP BY子句](../SQL-Manual/GroupBy-Clause_apache.md)指定的分组的一部分。 示例1:返回地址表中的总行数: diff --git a/src/zh/UserGuide/latest-Table/SQL-Manual/overview_apache.md b/src/zh/UserGuide/latest-Table/SQL-Manual/overview_apache.md index 4f8ca7579..81a373677 100644 --- a/src/zh/UserGuide/latest-Table/SQL-Manual/overview_apache.md +++ b/src/zh/UserGuide/latest-Table/SQL-Manual/overview_apache.md @@ -40,10 +40,10 @@ IoTDB 查询语法提供以下子句: - SELECT 子句:查询结果应包含的列。详细语法见:[SELECT子句](../SQL-Manual/Select-Clause_apache.md) - FROM 子句:指出查询的数据源,可以是单个表、多个通过 `JOIN` 子句连接的表,或者是一个子查询。详细语法见:[FROM & JOIN 子句](../SQL-Manual/From-Join-Clause.md) - WHERE 子句:用于过滤数据,只选择满足特定条件的数据行。这个子句在逻辑上紧跟在 FROM 子句之后执行。详细语法见:[WHERE 子句](../SQL-Manual/Where-Clause.md) -- GROUP BY 子句:当需要对数据进行聚合时使用,指定了用于分组的列。详细语法见:[GROUP BY 子句](../SQL-Manual/GroupBy-Clause.md) +- GROUP BY 子句:当需要对数据进行聚合时使用,指定了用于分组的列。详细语法见:[GROUP BY 子句](../SQL-Manual/GroupBy-Clause_apache.md) - HAVING 子句:在 GROUP BY 子句之后使用,用于对已经分组的数据进行过滤。与 WHERE 子句类似,但 HAVING 子句在分组后执行。详细语法见:[HAVING 子句](../SQL-Manual/Having-Clause.md) -- FILL 子句:用于处理查询结果中的空值,用户可以使用 FILL 子句来指定数据缺失时的填充模式(如前一个非空值或线性插值)来填充 null 值,以便于数据可视化和分析。 详细语法见:[FILL 子句](../SQL-Manual/Fill-Clause.md) -- ORDER BY 子句:对查询结果进行排序,可以指定升序(ASC)或降序(DESC),以及 NULL 值的处理方式(NULLS FIRST 或 NULLS LAST)。详细语法见:[ORDER BY 子句](../SQL-Manual/OrderBy-Clause.md) +- FILL 子句:用于处理查询结果中的空值,用户可以使用 FILL 子句来指定数据缺失时的填充模式(如前一个非空值或线性插值)来填充 null 值,以便于数据可视化和分析。 详细语法见:[FILL 子句](../SQL-Manual/Fill-Clause_apache.md) +- ORDER BY 子句:对查询结果进行排序,可以指定升序(ASC)或降序(DESC),以及 NULL 值的处理方式(NULLS FIRST 或 NULLS LAST)。详细语法见:[ORDER BY 子句](../SQL-Manual/OrderBy-Clause_apache.md) - OFFSET 子句:用于指定查询结果的起始位置,即跳过前 OFFSET 行。与 LIMIT 子句配合使用。详细语法见:[LIMIT 和 OFFSET 子句](../SQL-Manual/Limit-Offset-Clause.md) - LIMIT 子句:限制查询结果的行数,通常与 OFFSET 子句一起使用以实现分页功能。详细语法见:[LIMIT 和 OFFSET 子句](../SQL-Manual/Limit-Offset-Clause.md)