blob: ae64736133954cc53322ddb42f7a4d01a1fd8384 [file] [log] [blame] [view]
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
# SELECT 子句
## 1. 语法概览
```sql
SELECT setQuantifier? selectItem (',' selectItem)*
selectItem
: expression (AS? identifier)? #selectSingle
| tableName '.' ASTERISK (AS columnAliases)? #selectAll
| ASTERISK #selectAll
;
setQuantifier
: DISTINCT
| ALL
;
```
- **SELECT 子句**: 指定了查询结果应包含的列,包含聚合函数(如 SUM、AVG、COUNT 等)以及窗口函数,在逻辑上最后执行。
- **DISTINCT 关键字**: `SELECT DISTINCT column_name` 确保查询结果中的值是唯一的,去除重复项。
- **COLUMNS 函数**:SELECT 子句中支持使用 COLUMNS 函数进行列筛选,并支持和表达式结合使用,使表达式的效果对所有筛选出的列生效。
## 2. 语法详释:
每个 `selectItem` 可以是以下形式之一:
- **表达式**: `expression [ [ AS ] column_alias ]` 定义单个输出列,可以指定列别名。
- **选择某个关系的所有列**: `relation.*` 选择某个关系的所有列,不允许使用列别名。
- **选择结果集中的所有列**: `*` 选择查询的所有列,不允许使用列别名。
`DISTINCT` 的使用场景:
- **SELECT 语句**:在 SELECT 语句中使用 DISTINCT,查询结果去除重复项。
- **聚合函数**:与聚合函数一起使用时,DISTINCT 只处理输入数据集中的非重复行。
- **GROUP BY 子句**:在 GROUP BY 子句中使用 ALL 和 DISTINCT 量词,决定是否每个重复的分组集产生不同的输出行。
`COLUMNS` 函数:
- **`COLUMNS(*)`**: 匹配所有列,支持结合表达式进行使用。
- **`COLUMNS(regexStr) ? AS identifier`**:正则匹配
- 匹配所有列名满足正则表达式的列,支持结合表达式进行使用。
- 支持引用正则表达式捕获到的 groups 对列进行重命名,不写 AS 时展示原始列名(即 _coln_原始列名,其中 n 为列在结果表中的 position)。
- 重命名用法简述:
- regexStr 中使用圆括号设置要捕获的组;
- 在 identifier 中使用 `'$index'` 引用捕获到的组。
注意:使用该功能时,identifier 中会包含特殊字符 '$',所以整个 identifier 要用双引号引起来。
## 3. 示例数据
在[示例数据页面](../Reference/Sample-Data.md)中,包含了用于构建表结构和插入数据的SQL语句,下载并在IoTDB CLI中执行这些语句,即可将数据导入IoTDB,您可以使用这些数据来测试和执行示例中的SQL语句,并获得相应的结果。
### 3.1 选择列表
#### 3.1.1 星表达式
使用星号(*)可以选取表中的所有列,**注意**,星号表达式不能被大多数函数转换,除了`count(*)`的情况。
示例:从表中选择所有列
```sql
SELECT * FROM table1;
```
执行结果如下:
```sql
+-----------------------------+------+--------+---------+--------+-----------+-----------+--------+------+-----------------------------+
| time|region|plant_id|device_id|model_id|maintenance|temperature|humidity|status| modifytime|
+-----------------------------+------+--------+---------+--------+-----------+-----------+--------+------+-----------------------------+
|2024-11-29T11:00:00.000+08:00| 上海| 3002| 100| E| 180| null| 45.1| true| null|
|2024-11-29T18:30:00.000+08:00| 上海| 3002| 100| E| 180| 90.0| 35.4| true|2024-11-29T18:30:15.000+08:00|
|2024-11-28T08:00:00.000+08:00| 上海| 3001| 100| C| 90| 85.0| null| null|2024-11-28T08:00:09.000+08:00|
|2024-11-28T09:00:00.000+08:00| 上海| 3001| 100| C| 90| null| 40.9| true| null|
|2024-11-28T10:00:00.000+08:00| 上海| 3001| 100| C| 90| 85.0| 35.2| null|2024-11-28T10:00:11.000+08:00|
|2024-11-28T11:00:00.000+08:00| 上海| 3001| 100| C| 90| 88.0| 45.1| true|2024-11-28T11:00:12.000+08:00|
|2024-11-26T13:37:00.000+08:00| 北京| 1001| 100| A| 180| 90.0| 35.1| true|2024-11-26T13:37:34.000+08:00|
|2024-11-26T13:38:00.000+08:00| 北京| 1001| 100| A| 180| 90.0| 35.1| true|2024-11-26T13:38:25.000+08:00|
|2024-11-30T09:30:00.000+08:00| 上海| 3002| 101| F| 360| 90.0| 35.2| true| null|
|2024-11-30T14:30:00.000+08:00| 上海| 3002| 101| F| 360| 90.0| 34.8| true|2024-11-30T14:30:17.000+08:00|
|2024-11-29T10:00:00.000+08:00| 上海| 3001| 101| D| 360| 85.0| null| null|2024-11-29T10:00:13.000+08:00|
|2024-11-27T16:38:00.000+08:00| 北京| 1001| 101| B| 180| null| 35.1| true|2024-11-26T16:37:01.000+08:00|
|2024-11-27T16:39:00.000+08:00| 北京| 1001| 101| B| 180| 85.0| 35.3| null| null|
|2024-11-27T16:40:00.000+08:00| 北京| 1001| 101| B| 180| 85.0| null| null|2024-11-26T16:37:03.000+08:00|
|2024-11-27T16:41:00.000+08:00| 北京| 1001| 101| B| 180| 85.0| null| null|2024-11-26T16:37:04.000+08:00|
|2024-11-27T16:42:00.000+08:00| 北京| 1001| 101| B| 180| null| 35.2| false| null|
|2024-11-27T16:43:00.000+08:00| 北京| 1001| 101| B| 180| null| null| false| null|
|2024-11-27T16:44:00.000+08:00| 北京| 1001| 101| B| 180| null| null| false|2024-11-26T16:37:08.000+08:00|
+-----------------------------+------+--------+---------+--------+-----------+-----------+--------+------+-----------------------------+
Total line number = 18
It costs 0.653s
```
#### 3.1.2 聚合函数
聚合函数将多行数据汇总为单个值。当 SELECT 子句中存在聚合函数时,查询将被视为聚合查询。在聚合查询中,所有表达式必须是聚合函数的一部分或由[GROUP BY子句](../SQL-Manual/GroupBy-Clause.md)指定的分组的一部分。
示例1:返回地址表中的总行数:
```sql
SELECT count(*) FROM table1;
```
执行结果如下:
```sql
+-----+
|_col0|
+-----+
| 18|
+-----+
Total line number = 1
It costs 0.091s
```
示例2:返回按城市分组的地址表中的总行数:
```sql
SELECT region, count(*)
FROM table1
GROUP BY region;
```
执行结果如下:
```sql
+------+-----+
|region|_col1|
+------+-----+
| 上海| 9|
| 北京| 9|
+------+-----+
Total line number = 2
It costs 0.071s
```
#### 3.1.3 别名
关键字`AS`:为选定的列指定别名,别名将覆盖已存在的列名,以提高查询结果的可读性。
示例1:原始表格:
```sql
IoTDB> SELECT * FROM table1;
```
执行结果如下:
```sql
+-----------------------------+------+--------+---------+--------+-----------+-----------+--------+------+-----------------------------+
| time|region|plant_id|device_id|model_id|maintenance|temperature|humidity|status| modifytime|
+-----------------------------+------+--------+---------+--------+-----------+-----------+--------+------+-----------------------------+
|2024-11-29T11:00:00.000+08:00| 上海| 3002| 100| E| 180| null| 45.1| true| null|
|2024-11-29T18:30:00.000+08:00| 上海| 3002| 100| E| 180| 90.0| 35.4| true|2024-11-29T18:30:15.000+08:00|
|2024-11-28T08:00:00.000+08:00| 上海| 3001| 100| C| 90| 85.0| null| null|2024-11-28T08:00:09.000+08:00|
|2024-11-28T09:00:00.000+08:00| 上海| 3001| 100| C| 90| null| 40.9| true| null|
|2024-11-28T10:00:00.000+08:00| 上海| 3001| 100| C| 90| 85.0| 35.2| null|2024-11-28T10:00:11.000+08:00|
|2024-11-28T11:00:00.000+08:00| 上海| 3001| 100| C| 90| 88.0| 45.1| true|2024-11-28T11:00:12.000+08:00|
|2024-11-26T13:37:00.000+08:00| 北京| 1001| 100| A| 180| 90.0| 35.1| true|2024-11-26T13:37:34.000+08:00|
|2024-11-26T13:38:00.000+08:00| 北京| 1001| 100| A| 180| 90.0| 35.1| true|2024-11-26T13:38:25.000+08:00|
|2024-11-30T09:30:00.000+08:00| 上海| 3002| 101| F| 360| 90.0| 35.2| true| null|
|2024-11-30T14:30:00.000+08:00| 上海| 3002| 101| F| 360| 90.0| 34.8| true|2024-11-30T14:30:17.000+08:00|
|2024-11-29T10:00:00.000+08:00| 上海| 3001| 101| D| 360| 85.0| null| null|2024-11-29T10:00:13.000+08:00|
|2024-11-27T16:38:00.000+08:00| 北京| 1001| 101| B| 180| null| 35.1| true|2024-11-26T16:37:01.000+08:00|
|2024-11-27T16:39:00.000+08:00| 北京| 1001| 101| B| 180| 85.0| 35.3| null| null|
|2024-11-27T16:40:00.000+08:00| 北京| 1001| 101| B| 180| 85.0| null| null|2024-11-26T16:37:03.000+08:00|
|2024-11-27T16:41:00.000+08:00| 北京| 1001| 101| B| 180| 85.0| null| null|2024-11-26T16:37:04.000+08:00|
|2024-11-27T16:42:00.000+08:00| 北京| 1001| 101| B| 180| null| 35.2| false| null|
|2024-11-27T16:43:00.000+08:00| 北京| 1001| 101| B| 180| null| null| false| null|
|2024-11-27T16:44:00.000+08:00| 北京| 1001| 101| B| 180| null| null| false|2024-11-26T16:37:08.000+08:00|
+-----------------------------+------+--------+---------+--------+-----------+-----------+--------+------+-----------------------------+
Total line number = 18
It costs 0.653s
```
示例2:单列设置别名:
```sql
IoTDB> SELECT device_id
AS device
FROM table1;
```
执行结果如下:
```sql
+------+
|device|
+------+
| 100|
| 100|
| 100|
| 100|
| 100|
| 100|
| 100|
| 100|
| 101|
| 101|
| 101|
| 101|
| 101|
| 101|
| 101|
| 101|
| 101|
| 101|
+------+
Total line number = 18
It costs 0.053s
```
示例3:所有列的别名:
```sql
IoTDB> SELECT table1.*
AS (timestamp, Reg, Pl, DevID, Mod, Mnt, Temp, Hum, Stat,MTime)
FROM table1;
```
执行结果如下:
```sql
+-----------------------------+----+----+-----+---+---+----+----+-----+-----------------------------+
| TIMESTAMP| REG| PL|DEVID|MOD|MNT|TEMP| HUM| STAT| MTIME|
+-----------------------------+----+----+-----+---+---+----+----+-----+-----------------------------+
|2024-11-29T11:00:00.000+08:00|上海|3002| 100| E|180|null|45.1| true| null|
|2024-11-29T18:30:00.000+08:00|上海|3002| 100| E|180|90.0|35.4| true|2024-11-29T18:30:15.000+08:00|
|2024-11-28T08:00:00.000+08:00|上海|3001| 100| C| 90|85.0|null| null|2024-11-28T08:00:09.000+08:00|
|2024-11-28T09:00:00.000+08:00|上海|3001| 100| C| 90|null|40.9| true| null|
|2024-11-28T10:00:00.000+08:00|上海|3001| 100| C| 90|85.0|35.2| null|2024-11-28T10:00:11.000+08:00|
|2024-11-28T11:00:00.000+08:00|上海|3001| 100| C| 90|88.0|45.1| true|2024-11-28T11:00:12.000+08:00|
|2024-11-26T13:37:00.000+08:00|北京|1001| 100| A|180|90.0|35.1| true|2024-11-26T13:37:34.000+08:00|
|2024-11-26T13:38:00.000+08:00|北京|1001| 100| A|180|90.0|35.1| true|2024-11-26T13:38:25.000+08:00|
|2024-11-30T09:30:00.000+08:00|上海|3002| 101| F|360|90.0|35.2| true| null|
|2024-11-30T14:30:00.000+08:00|上海|3002| 101| F|360|90.0|34.8| true|2024-11-30T14:30:17.000+08:00|
|2024-11-29T10:00:00.000+08:00|上海|3001| 101| D|360|85.0|null| null|2024-11-29T10:00:13.000+08:00|
|2024-11-27T16:38:00.000+08:00|北京|1001| 101| B|180|null|35.1| true|2024-11-26T16:37:01.000+08:00|
|2024-11-27T16:39:00.000+08:00|北京|1001| 101| B|180|85.0|35.3| null| null|
|2024-11-27T16:40:00.000+08:00|北京|1001| 101| B|180|85.0|null| null|2024-11-26T16:37:03.000+08:00|
|2024-11-27T16:41:00.000+08:00|北京|1001| 101| B|180|85.0|null| null|2024-11-26T16:37:04.000+08:00|
|2024-11-27T16:42:00.000+08:00|北京|1001| 101| B|180|null|35.2|false| null|
|2024-11-27T16:43:00.000+08:00|北京|1001| 101| B|180|null|null|false| null|
|2024-11-27T16:44:00.000+08:00|北京|1001| 101| B|180|null|null|false|2024-11-26T16:37:08.000+08:00|
+-----------------------------+----+----+-----+---+---+----+----+-----+-----------------------------+
Total line number = 18
It costs 0.189s
```
### 3.2 Columns 函数
1. 不结合表达式
```sql
-- 查询列名以 'm' 开头的列的数据
IoTDB:database1> select columns('^m.*') from table1 limit 5
+--------+-----------+
|model_id|maintenance|
+--------+-----------+
| E| 180|
| E| 180|
| C| 90|
| C| 90|
| C| 90|
+--------+-----------+
-- 查询列名以 'o' 开头的列,未匹配到任何列,抛出异常
IoTDB:database1> select columns('^o.*') from table1 limit 5
Msg: org.apache.iotdb.jdbc.IoTDBSQLException: 701: No matching columns found that match regex '^o.*'
-- 查询列名以 'm' 开头的列的数据,并重命名以 'series_' 开头
IoTDB:database1> select columns('^m(.*)') AS "series_$0" from table1 limit 5
+---------------+------------------+
|series_model_id|series_maintenance|
+---------------+------------------+
| E| 180|
| E| 180|
| C| 90|
| C| 90|
| C| 90|
+---------------+------------------+
```
2. 结合表达式
- 单个 COLUMNS 函数
```sql
-- 查询所有列的最小值
IoTDB:database1> select min(columns(*)) from table1
+-----------------------------+------------+--------------+---------------+--------------+-----------------+-----------------+--------------+------------+-----------------------------+
| _col0_time|_col1_region|_col2_plant_id|_col3_device_id|_col4_model_id|_col5_maintenance|_col6_temperature|_col7_humidity|_col8_status| _col9_arrival_time|
+-----------------------------+------------+--------------+---------------+--------------+-----------------+-----------------+--------------+------------+-----------------------------+
|2024-11-26T13:37:00.000+08:00| 上海| 1001| 100| A| 180| 85.0| 34.8| false|2024-11-26T13:37:34.000+08:00|
+-----------------------------+------------+--------------+---------------+--------------+-----------------+-----------------+--------------+------------+-----------------------------+
```
- 多个 COLUMNS 函数,出现在同一表达式
> 使用限制:出现多个 COLUMNS 函数时,多个 COLUMNS 函数的参数要完全相同
```sql
-- 查询 'h' 开头列的最小值和最大值之和
IoTDB:database1> select min(columns('^h.*')) + max(columns('^h.*')) from table1
+--------------+
|_col0_humidity|
+--------------+
| 79.899994|
+--------------+
-- 错误查询,两个 COLUMNS 函数不完全相同
IoTDB:database1> select min(columns('^h.*')) + max(columns('^t.*')) from table1
Msg: org.apache.iotdb.jdbc.IoTDBSQLException: 701: Multiple different COLUMNS in the same expression are not supported
```
- 多个 COLUMNS 函数,出现在不同表达式
```sql
-- 分别查询 'h' 开头列的最小值和最大值
IoTDB:database1> select min(columns('^h.*')) , max(columns('^h.*')) from table1
+--------------+--------------+
|_col0_humidity|_col1_humidity|
+--------------+--------------+
| 34.8| 45.1|
+--------------+--------------+
-- 分别查询 'h' 开头列的最小值和 'te'开头列的最大值
IoTDB:database1> select min(columns('^h.*')) , max(columns('^te.*')) from table1
+--------------+-----------------+
|_col0_humidity|_col1_temperature|
+--------------+-----------------+
| 34.8| 90.0|
+--------------+-----------------+
```
3. 在 WHERE 子句中使用
```sql
-- 查询数据,所有 'h' 开头列的数据必须要大于 40
IoTDB:database1> select * from table1 where columns('^h.*') > 40
+-----------------------------+------+--------+---------+--------+-----------+-----------+--------+------+-----------------------------+
| time|region|plant_id|device_id|model_id|maintenance|temperature|humidity|status| arrival_time|
+-----------------------------+------+--------+---------+--------+-----------+-----------+--------+------+-----------------------------+
|2024-11-29T11:00:00.000+08:00| 上海| 3002| 100| E| 180| null| 45.1| true| null|
|2024-11-28T09:00:00.000+08:00| 上海| 3001| 100| C| 90| null| 40.9| true| null|
|2024-11-28T11:00:00.000+08:00| 上海| 3001| 100| C| 90| 88.0| 45.1| true|2024-11-28T11:00:12.000+08:00|
+-----------------------------+------+--------+---------+--------+-----------+-----------+--------+------+-----------------------------+
--等价于
IoTDB:database1> select * from table1 where humidity > 40
+-----------------------------+------+--------+---------+--------+-----------+-----------+--------+------+-----------------------------+
| time|region|plant_id|device_id|model_id|maintenance|temperature|humidity|status| arrival_time|
+-----------------------------+------+--------+---------+--------+-----------+-----------+--------+------+-----------------------------+
|2024-11-29T11:00:00.000+08:00| 上海| 3002| 100| E| 180| null| 45.1| true| null|
|2024-11-28T09:00:00.000+08:00| 上海| 3001| 100| C| 90| null| 40.9| true| null|
|2024-11-28T11:00:00.000+08:00| 上海| 3001| 100| C| 90| 88.0| 45.1| true|2024-11-28T11:00:12.000+08:00|
+-----------------------------+------+--------+---------+--------+-----------+-----------+--------+------+-----------------------------+
```
## 4. 结果集列顺序
- **列顺序**: 结果集中的列顺序与 SELECT 子句中指定的顺序相同。
- **多列排序**: 如果选择表达式返回多个列,它们的排序方式与源关系中的排序方式相同