数据查询

概述

在 IoTDB 中,使用 SELECT 语句从一条或多条时间序列中查询数据。

语法定义

1. SELECT [LAST] selectExpr [, selectExpr] ...
2. [INTO intoItem [, intoItem] ...]
3. FROM prefixPath [, prefixPath] ...
4. [WHERE whereCondition]
5. [GROUP BY {
6. ([startTime, endTime), interval [, slidingStep]) |
7. LEVEL = levelNum [, levelNum] ... |
8. TAGS(tagKey [, tagKey] ... |
9. VARIATION(expression[,delta][,ignoreNull=true/false])|
10. CONDITION(expression,[keep>/>=/=/</<=]threshold[,ignoreNull=true/false])|
11. SESSION(timeInterval)
12. }]
13. [HAVING havingCondition]
14. [ORDER BY sortKey {ASC | DESC}]
15. [FILL ({PREVIOUS | LINEAR | constant})]
16. [SLIMIT seriesLimit] [SOFFSET seriesOffset]
17. [LIMIT rowLimit] [OFFSET rowOffset]
18. [ALIGN BY {TIME | DEVICE}]

语法说明

SELECT 子句

  • SELECT 子句指定查询的输出,由若干个 selectExpr 组成。
  • 每个 selectExpr 定义查询结果中的一列或多列,它是一个由时间序列路径后缀、常量、函数和运算符组成的表达式。
  • 支持使用AS为查询结果集中的列指定别名。
  • 在 SELECT 子句中使用 LAST 关键词可以指定查询为最新点查询,详细说明及示例见文档 最新点查询 。
  • 详细说明及示例见文档 选择表达式 。

INTO 子句

  • SELECT INTO 用于将查询结果写入一系列指定的时间序列中。INTO 子句指定了查询结果写入的目标时间序列。
  • 详细说明及示例见文档 SELECT INTO(查询写回) 。

FROM 子句

  • FROM 子句包含要查询的一个或多个时间序列的路径前缀,支持使用通配符。
  • 在执行查询时,会将 FROM 子句中的路径前缀和 SELECT 子句中的后缀进行拼接得到完整的查询目标序列。

WHERE 子句

  • WHERE 子句指定了对数据行的筛选条件,由一个 whereCondition 组成。
  • whereCondition 是一个逻辑表达式,对于要选择的每一行,其计算结果为真。如果没有 WHERE 子句,将选择所有行。
  • 在 whereCondition 中,可以使用除聚合函数之外的任何 IOTDB 支持的函数和运算符。
  • 详细说明及示例见文档 查询过滤条件 。

GROUP BY 子句

  • GROUP BY 子句指定对序列进行分段或分组聚合的方式。
  • 分段聚合是指按照时间维度,针对同时间序列中不同数据点之间的时间关系,对数据在行的方向进行分段,每个段得到一个聚合值。目前支持时间区间分段、差值分段、条件分段和会话分段,未来将支持更多分段方式。
  • 分组聚合是指针对不同时间序列,在时间序列的潜在业务属性上分组,每个组包含若干条时间序列,每个组得到一个聚合值。支持按路径层级分组和按序列标签分组两种分组方式。
  • 分段聚合和分组聚合可以混合使用。
  • 详细说明及示例见文档 分段分组聚合 。

HAVING 子句

  • HAVING 子句指定了对聚合结果的筛选条件,由一个 havingCondition 组成。
  • havingCondition 是一个逻辑表达式,对于要选择的聚合结果,其计算结果为真。如果没有 HAVING 子句,将选择所有聚合结果。
  • HAVING 要和聚合函数以及 GROUP BY 子句一起使用。
  • 详细说明及示例见文档 聚合结果过滤 。

ORDER BY 子句

  • ORDER BY 子句用于指定结果集的排序方式。
  • 按时间对齐模式下:默认按照时间戳大小升序排列,可以通过 ORDER BY TIME DESC 指定结果集按照时间戳大小降序排列。
  • 按设备对齐模式下:默认按照设备名的字典序升序排列,每个设备内部按照时间戳大小升序排列,可以通过 ORDER BY 子句调整设备列和时间列的排序优先级。
  • 详细说明及示例见文档 结果集排序。

FILL 子句

  • FILL 子句用于指定数据缺失情况下的填充模式,允许用户按照特定的方法对任何查询的结果集填充空值。
  • 详细说明及示例见文档 结果集补空值 。

SLIMIT 和 SOFFSET 子句

  • SLIMIT 指定查询结果的列数,SOFFSET 指定查询结果显示的起始列位置。SLIMIT 和 SOFFSET 仅用于控制值列,对时间列和设备列无效。
  • 关于查询结果分页,详细说明及示例见文档 结果集分页 。

LIMIT 和 OFFSET 子句

  • LIMIT 指定查询结果的行数,OFFSET 指定查询结果显示的起始行位置。
  • 关于查询结果分页,详细说明及示例见文档 结果集分页 。

ALIGN BY 子句

  • 查询结果集默认按时间对齐,包含一列时间列和若干个值列,每一行数据各列的时间戳相同。
  • 除按时间对齐之外,还支持按设备对齐,查询结果集包含一列时间列、一列设备列和若干个值列。
  • 详细说明及示例见文档 查询对齐模式 。

SQL 示例

示例1:根据一个时间区间选择一列数据

SQL 语句为:

1. select temperature from root.ln.wf01.wt01 where time < 2017-11-01T00:08:00.000

其含义为:

被选择的设备为 ln 集团 wf01 子站 wt01 设备;被选择的时间序列为温度传感器(temperature);该语句要求选择出该设备在 “2017-11-01T00:08:00.000” 时间点以前的所有温度传感器的值。

该 SQL 语句的执行结果如下:

1. +-----------------------------+-----------------------------+
2. |                         Time|root.ln.wf01.wt01.temperature|
3. +-----------------------------+-----------------------------+
4. |2017-11-01T00:00:00.000+08:00|                        25.96|
5. |2017-11-01T00:01:00.000+08:00|                        24.36|
6. |2017-11-01T00:02:00.000+08:00|                        20.09|
7. |2017-11-01T00:03:00.000+08:00|                        20.18|
8. |2017-11-01T00:04:00.000+08:00|                        21.13|
9. |2017-11-01T00:05:00.000+08:00|                        22.72|
10. |2017-11-01T00:06:00.000+08:00|                        20.71|
11. |2017-11-01T00:07:00.000+08:00|                        21.45|
12. +-----------------------------+-----------------------------+
13. Total line number = 8
14. It costs 0.026s

示例2:根据一个时间区间选择多列数据

SQL 语句为:

1. select status, temperature from root.ln.wf01.wt01 where time > 2017-11-01T00:05:00.000 and time < 2017-11-01T00:12:00.000;

其含义为:

被选择的设备为 ln 集团 wf01 子站 wt01 设备;被选择的时间序列为供电状态(status)和温度传感器(temperature);该语句要求选择出 “2017-11-01T00:05:00.000” 至 “2017-11-01T00:12:00.000” 之间的所选时间序列的值。

该 SQL 语句的执行结果如下:

1. +-----------------------------+------------------------+-----------------------------+
2. |                         Time|root.ln.wf01.wt01.status|root.ln.wf01.wt01.temperature|
3. +-----------------------------+------------------------+-----------------------------+
4. |2017-11-01T00:06:00.000+08:00|                   false|                        20.71|
5. |2017-11-01T00:07:00.000+08:00|                   false|                        21.45|
6. |2017-11-01T00:08:00.000+08:00|                   false|                        22.58|
7. |2017-11-01T00:09:00.000+08:00|                   false|                        20.98|
8. |2017-11-01T00:10:00.000+08:00|                    true|                        25.52|
9. |2017-11-01T00:11:00.000+08:00|                   false|                        22.91|
10. +-----------------------------+------------------------+-----------------------------+
11. Total line number = 6
12. It costs 0.018s

示例3:按照多个时间区间选择同一设备的多列数据

IoTDB 支持在一次查询中指定多个时间区间条件,用户可以根据需求随意组合时间区间条件。例如,

SQL 语句为:

1. select status, temperature from root.ln.wf01.wt01 where (time > 2017-11-01T00:05:00.000 and time < 2017-11-01T00:12:00.000) or (time >= 2017-11-01T16:35:00.000 and time <= 2017-11-01T16:37:00.000);

其含义为:

被选择的设备为 ln 集团 wf01 子站 wt01 设备;被选择的时间序列为“供电状态(status)”和“温度传感器(temperature)”;该语句指定了两个不同的时间区间,分别为“2017-11-01T00:05:00.000 至 2017-11-01T00:12:00.000”和“2017-11-01T16:35:00.000 至 2017-11-01T16:37:00.000”;该语句要求选择出满足任一时间区间的被选时间序列的值。

该 SQL 语句的执行结果如下:

1. +-----------------------------+------------------------+-----------------------------+
2. |                         Time|root.ln.wf01.wt01.status|root.ln.wf01.wt01.temperature|
3. +-----------------------------+------------------------+-----------------------------+
4. |2017-11-01T00:06:00.000+08:00|                   false|                        20.71|
5. |2017-11-01T00:07:00.000+08:00|                   false|                        21.45|
6. |2017-11-01T00:08:00.000+08:00|                   false|                        22.58|
7. |2017-11-01T00:09:00.000+08:00|                   false|                        20.98|
8. |2017-11-01T00:10:00.000+08:00|                    true|                        25.52|
9. |2017-11-01T00:11:00.000+08:00|                   false|                        22.91|
10. |2017-11-01T16:35:00.000+08:00|                    true|                        23.44|
11. |2017-11-01T16:36:00.000+08:00|                   false|                        21.98|
12. |2017-11-01T16:37:00.000+08:00|                   false|                        21.93|
13. +-----------------------------+------------------------+-----------------------------+
14. Total line number = 9
15. It costs 0.018s

示例4:按照多个时间区间选择不同设备的多列数据

该系统支持在一次查询中选择任意列的数据,也就是说,被选择的列可以来源于不同的设备。例如,SQL 语句为:

1. select wf01.wt01.status, wf02.wt02.hardware from root.ln where (time > 2017-11-01T00:05:00.000 and time < 2017-11-01T00:12:00.000) or (time >= 2017-11-01T16:35:00.000 and time <= 2017-11-01T16:37:00.000);

其含义为:

被选择的时间序列为 “ln 集团 wf01 子站 wt01 设备的供电状态” 以及 “ln 集团 wf02 子站 wt02 设备的硬件版本”;该语句指定了两个时间区间,分别为 “2017-11-01T00:05:00.000 至 2017-11-01T00:12:00.000” 和 “2017-11-01T16:35:00.000 至 2017-11-01T16:37:00.000”;该语句要求选择出满足任意时间区间的被选时间序列的值。

该 SQL 语句的执行结果如下:

1. +-----------------------------+------------------------+--------------------------+
2. |                         Time|root.ln.wf01.wt01.status|root.ln.wf02.wt02.hardware|
3. +-----------------------------+------------------------+--------------------------+
4. |2017-11-01T00:06:00.000+08:00|                   false|                        v1|
5. |2017-11-01T00:07:00.000+08:00|                   false|                        v1|
6. |2017-11-01T00:08:00.000+08:00|                   false|                        v1|
7. |2017-11-01T00:09:00.000+08:00|                   false|                        v1|
8. |2017-11-01T00:10:00.000+08:00|                    true|                        v2|
9. |2017-11-01T00:11:00.000+08:00|                   false|                        v1|
10. |2017-11-01T16:35:00.000+08:00|                    true|                        v2|
11. |2017-11-01T16:36:00.000+08:00|                   false|                        v1|
12. |2017-11-01T16:37:00.000+08:00|                   false|                        v1|
13. +-----------------------------+------------------------+--------------------------+
14. Total line number = 9
15. It costs 0.014s

示例5:根据时间降序返回结果集

IoTDB 支持 order by time 语句,用于对结果按照时间进行降序展示。例如,SQL 语句为:

1. select * from root.ln.** where time > 1 order by time desc limit 10;

语句执行的结果为:

1. +-----------------------------+--------------------------+------------------------+-----------------------------+------------------------+
2. |                         Time|root.ln.wf02.wt02.hardware|root.ln.wf02.wt02.status|root.ln.wf01.wt01.temperature|root.ln.wf01.wt01.status|
3. +-----------------------------+--------------------------+------------------------+-----------------------------+------------------------+
4. |2017-11-07T23:59:00.000+08:00|                        v1|                   false|                        21.07|                   false|
5. |2017-11-07T23:58:00.000+08:00|                        v1|                   false|                        22.93|                   false|
6. |2017-11-07T23:57:00.000+08:00|                        v2|                    true|                        24.39|                    true|
7. |2017-11-07T23:56:00.000+08:00|                        v2|                    true|                        24.44|                    true|
8. |2017-11-07T23:55:00.000+08:00|                        v2|                    true|                         25.9|                    true|
9. |2017-11-07T23:54:00.000+08:00|                        v1|                   false|                        22.52|                   false|
10. |2017-11-07T23:53:00.000+08:00|                        v2|                    true|                        24.58|                    true|
11. |2017-11-07T23:52:00.000+08:00|                        v1|                   false|                        20.18|                   false|
12. |2017-11-07T23:51:00.000+08:00|                        v1|                   false|                        22.24|                   false|
13. |2017-11-07T23:50:00.000+08:00|                        v2|                    true|                         23.7|                    true|
14. +-----------------------------+--------------------------+------------------------+-----------------------------+------------------------+
15. Total line number = 10
16. It costs 0.016s

查询执行接口

在 IoTDB 中,提供两种方式执行数据查询操作:

  • 使用 IoTDB-SQL 执行查询。
  • 常用查询的高效执行接口,包括时间序列原始数据范围查询、最新点查询、简单聚合查询。

使用 IoTDB-SQL 执行查询

数据查询语句支持在 SQL 命令行终端、JDBC、JAVA / C++ / Python / Go 等编程语言 API、RESTful API 中使用。

  • 在 SQL 命令行终端中执行查询语句:启动 SQL 命令行终端,直接输入查询语句执行即可,详见 SQL 命令行终端。
  • 在 JDBC 中执行查询语句,详见 JDBC 。
  • 在 JAVA / C++ / Python / Go 等编程语言 API 中执行查询语句,详见应用编程接口一章相应文档。接口原型如下:

1. SessionDataSet executeQueryStatement(String sql); - 在 RESTful API 中使用,详见 HTTP API V1 或者 HTTP API V2。

常用查询的高效执行接口

各编程语言的 API 为常用的查询提供了高效执行接口,可以省去 SQL 解析等操作的耗时。包括:

  • 时间序列原始数据范围查询:
  • 指定的查询时间范围为左闭右开区间,包含开始时间但不包含结束时间。
1. SessionDataSet executeRawDataQuery(List<String> paths, long startTime, long endTime);
  • 最新点查询:
  • 查询最后一条时间戳大于等于某个时间点的数据。
1. SessionDataSet executeLastDataQuery(List<String> paths, long lastTime);
  • 聚合查询:
  • 支持指定查询时间范围。指定的查询时间范围为左闭右开区间,包含开始时间但不包含结束时间。
  • 支持按照时间区间分段查询。
1. SessionDataSet executeAggregationQuery(List<String> paths, List<Aggregation> aggregations);

3. SessionDataSet executeAggregationQuery(
4. List<String> paths, List<Aggregation> aggregations, long startTime, long endTime);

6. SessionDataSet executeAggregationQuery(
7. List<String> paths,
8. List<Aggregation> aggregations,
9. long startTime,
10. long endTime,
11. long interval);

13. SessionDataSet executeAggregationQuery(
14. List<String> paths,
15. List<Aggregation> aggregations,
16. long startTime,
17. long endTime,
18. long interval,
19. long slidingStep);