跳至主要內容

数据查询

...大约 11 分钟

数据查询

概述

在 IoTDB 中,使用 SELECT 语句从一条或多条时间序列中查询数据,IoTDB 不区分历史数据和实时数据,用户可以用统一的sql语法进行查询,通过 WHERE 子句中的时间过滤谓词决定查询的时间范围。

语法定义

SELECT [LAST] selectExpr [, selectExpr] ...
    [INTO intoItem [, intoItem] ...]
    FROM prefixPath [, prefixPath] ...
    [WHERE whereCondition]
    [GROUP BY {
        ([startTime, endTime), interval [, slidingStep]) |
        LEVEL = levelNum [, levelNum] ... |
        TAGS(tagKey [, tagKey] ... |
        VARIATION(expression[,delta][,ignoreNull=true/false])|
        CONDITION(expression,[keep>/>=/=/</<=]threshold[,ignoreNull=true/false])|
        SESSION(timeInterval)
    }]
    [HAVING havingCondition]
    [ORDER BY sortKey {ASC | DESC}]
    [FILL ({PREVIOUS | LINEAR | constant})]
    [SLIMIT seriesLimit] [SOFFSET seriesOffset]
    [LIMIT rowLimit] [OFFSET rowOffset]
    [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 子句用于指定数据缺失情况下的填充模式,允许用户按照特定的方法对任何查询的结果集填充空值。
  • 详细说明及示例见文档 结果集补空值

SLIMITSOFFSET 子句

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

LIMITOFFSET 子句

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

ALIGN BY 子句

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

SQL 示例

IoTDB 支持即席(Ad_hoc)查询,即支持用户在使用系统时,自定义查询条件,根据自己当时的需求写出查询sql并执行。用户可以通过上述介绍的子句,进行组合,指定任意合法的过滤条件来满足当时的查询需求,下面介绍了一些查询的示例:

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

SQL 语句为:

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 语句的执行结果如下:

+-----------------------------+-----------------------------+
|                         Time|root.ln.wf01.wt01.temperature|
+-----------------------------+-----------------------------+
|2017-11-01T00:00:00.000+08:00|                        25.96|
|2017-11-01T00:01:00.000+08:00|                        24.36|
|2017-11-01T00:02:00.000+08:00|                        20.09|
|2017-11-01T00:03:00.000+08:00|                        20.18|
|2017-11-01T00:04:00.000+08:00|                        21.13|
|2017-11-01T00:05:00.000+08:00|                        22.72|
|2017-11-01T00:06:00.000+08:00|                        20.71|
|2017-11-01T00:07:00.000+08:00|                        21.45|
+-----------------------------+-----------------------------+
Total line number = 8
It costs 0.026s

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

SQL 语句为:

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 语句的执行结果如下:

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

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

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

SQL 语句为:

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 语句的执行结果如下:

+-----------------------------+------------------------+-----------------------------+
|                         Time|root.ln.wf01.wt01.status|root.ln.wf01.wt01.temperature|
+-----------------------------+------------------------+-----------------------------+
|2017-11-01T00:06:00.000+08:00|                   false|                        20.71|
|2017-11-01T00:07:00.000+08:00|                   false|                        21.45|
|2017-11-01T00:08:00.000+08:00|                   false|                        22.58|
|2017-11-01T00:09:00.000+08:00|                   false|                        20.98|
|2017-11-01T00:10:00.000+08:00|                    true|                        25.52|
|2017-11-01T00:11:00.000+08:00|                   false|                        22.91|
|2017-11-01T16:35:00.000+08:00|                    true|                        23.44|
|2017-11-01T16:36:00.000+08:00|                   false|                        21.98|
|2017-11-01T16:37:00.000+08:00|                   false|                        21.93|
+-----------------------------+------------------------+-----------------------------+
Total line number = 9
It costs 0.018s

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

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

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 语句的执行结果如下:

+-----------------------------+------------------------+--------------------------+
|                         Time|root.ln.wf01.wt01.status|root.ln.wf02.wt02.hardware|
+-----------------------------+------------------------+--------------------------+
|2017-11-01T00:06:00.000+08:00|                   false|                        v1|
|2017-11-01T00:07:00.000+08:00|                   false|                        v1|
|2017-11-01T00:08:00.000+08:00|                   false|                        v1|
|2017-11-01T00:09:00.000+08:00|                   false|                        v1|
|2017-11-01T00:10:00.000+08:00|                    true|                        v2|
|2017-11-01T00:11:00.000+08:00|                   false|                        v1|
|2017-11-01T16:35:00.000+08:00|                    true|                        v2|
|2017-11-01T16:36:00.000+08:00|                   false|                        v1|
|2017-11-01T16:37:00.000+08:00|                   false|                        v1|
+-----------------------------+------------------------+--------------------------+
Total line number = 9
It costs 0.014s

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

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

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

语句执行的结果为:

+-----------------------------+--------------------------+------------------------+-----------------------------+------------------------+
|                         Time|root.ln.wf02.wt02.hardware|root.ln.wf02.wt02.status|root.ln.wf01.wt01.temperature|root.ln.wf01.wt01.status|
+-----------------------------+--------------------------+------------------------+-----------------------------+------------------------+
|2017-11-07T23:59:00.000+08:00|                        v1|                   false|                        21.07|                   false|
|2017-11-07T23:58:00.000+08:00|                        v1|                   false|                        22.93|                   false|
|2017-11-07T23:57:00.000+08:00|                        v2|                    true|                        24.39|                    true|
|2017-11-07T23:56:00.000+08:00|                        v2|                    true|                        24.44|                    true|
|2017-11-07T23:55:00.000+08:00|                        v2|                    true|                         25.9|                    true|
|2017-11-07T23:54:00.000+08:00|                        v1|                   false|                        22.52|                   false|
|2017-11-07T23:53:00.000+08:00|                        v2|                    true|                        24.58|                    true|
|2017-11-07T23:52:00.000+08:00|                        v1|                   false|                        20.18|                   false|
|2017-11-07T23:51:00.000+08:00|                        v1|                   false|                        22.24|                   false|
|2017-11-07T23:50:00.000+08:00|                        v2|                    true|                         23.7|                    true|
+-----------------------------+--------------------------+------------------------+-----------------------------+------------------------+
Total line number = 10
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 中执行查询语句,详见应用编程接口一章相应文档。接口原型如下:

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

常用查询的高效执行接口

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

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

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

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

SessionDataSet executeAggregationQuery(
    List<String> paths,
    List<Aggregation> aggregations,
    long startTime,
    long endTime,
    long interval,
    long slidingStep);

Copyright © 2024 The Apache Software Foundation.
Apache IoTDB, IoTDB, Apache, the Apache feather logo, and the Apache IoTDB project logo are either registered trademarks or trademarks of The Apache Software Foundation in all countries

Have a question? Connect with us on QQ, WeChat, or Slack. Join the community now.