准备数据
数据来源: 阿里云提供InfluxDB示例数据。示例数据是美国国家海洋和大气管理局(NOAA)业务海洋产品和服务中心的公开数据。该数据包括在2015年8月18日至2015年9月18日期间,在两个站点(加州Santa Monica(ID 9410840)和加州Coyote Creek(ID 9414575))上收集到的水位(ft)观测值,这些数值每6秒收集一次,总共15,258个观测值。
请注意,average_temperature
、h2o_pH
、h2o_quality
和h2o_temperature
这些measurement中包含有虚构的数据,这些数据用于阐明Schema探索中的查询功能。
数据下载地址:
1 | curl https://gist.githubusercontent.com/Maihj/5ee8f25aa025671be49e56a1329db38e/raw/4132e06b4b149db692107387250bdaebf10643e5/NOAA_data.txt -o NOAA_data.txt |
1 | influx -host localhost -port 8086 -import -path=NOAA_data.txt -precision=s -database=NOAA_water_database |
查看数据:
1 | influx -precision rfc3339 |
如果配置了 ssl 需要:
1 | influx -ssl -username <> -password <password> -host <> -port <> -precision rfc3339 -database <> |
查看示例数据中的 所有的 measurement 。
1 | show measurement |
1 | show measurements |
统计在measurement h2o_feet
中,非null
的water_level
的值的数量:
1 | SELECT COUNT("water_level") FROM h2o_feet |
在h2o_feet
中查询前五个观察值:
1 | > SELECT * FROM h2o_feet LIMIT 5 |
数据探索
概述
InfluxQL是一种类似SQL的查询语言,用于与InfluxDB中的数据进行交互。下面将详细介绍InfluxQL的SELECT语句和实用的数据查询语法。
基础 | 查询结果的配置 | 有关查询语法的提示 |
---|---|---|
SELECT语句 | ORDER BY time DESC | 时间语法 |
WHERE子句 | LIMIT和SLIMIT子句 | 正则表达式 |
GROUP BY子句 | OFFSET和SOFFSET子句 | 数据类型和转换 |
INTO子句 | 时区子句 | 合并 |
- | - | 多个语句 |
- | - | 子查询 |
在前面的示例数据中,如在 h2o_feet 的表中:
time | level description | location | water_level |
---|---|---|---|
2015-08-18T00:00:00Z | between 6 and 9 feet | coyote_creek | 8.12 |
2015-08-18T00:00:00Z | below 3 feet | santa_monica | 2.064 |
2015-08-18T00:06:00Z | between 6 and 9 feet | coyote_creek | 8.005 |
2015-08-18T00:06:00Z | below 3 feet | santa_monica | 2.116 |
2015-08-18T00:12:00Z | between 6 and 9 feet | coyote_creek | 7.887 |
2015-08-18T00:12:00Z | below 3 feet | santa_monica | 2.028 |
h2o_feet
中的数据以六分钟为间隔。h2o_feet
有一个tag key(location
),它有两个tag value:coyote_creek
和santa_monica
。h2o_feet
还有两个field:level description
存储字符串类型的field value,而water_level
存储浮点类型的field value。所有这些数据都存在数据库NOAA_water_database
中。
SELECT语句
SELECT
语句从一个或多个measurement中查询数据。
1 | SELECT <field_key>[,<field_key>,<tag_key>] FROM <measurement_name>[,<measurement_name>] |
SELECT
子句支持多种指定数据的格式:
SELECT *
返回所有的field和tag。SELECT ""
返回一个特定的field。SELECT "",""
返回多个field。SELECT "",""
返回一个特定的field和一个特定的tag,当SELECT
子句包含tag时,它必须至少指定一个field。SELECT ""::field,""::tag
返回一个特定的field和一个特定的tag。::[field | tag]
语法指定了标识符的类型,使用这个语法是为了区分具有相同名字的field key和tag key。
除此之外,SELECT
子句支持的功能还有:算术运算、函数、转换操作和正则表达式。
From
FROM
子句支持多种指定measurement的格式:
FROM
从一个measurement中返回数据。如果您使用CLI查询数据,那么访问的measurement属于USE
指定的数据库,并且使用的是默认保留策略。如果您使用的是HTTP API,那么measurement属于参数db
指定的数据库,同样,使用的是默认(DEFAULT
)的保留策略。
FROM ,
从多个measurement中返回数据。
FROM ..
从一个被完全限定的measurement中返回数据。通过明确指定measurement的数据库和保留策略来完全限定一个measurement。
FROM ..
从用户指定的一个数据库并使用默认保留策略的measurement中返回数据。
除此之外,FROM
子句还支持的功能:正则表达式。
引号
如果标识符包含除了[A-z,0-9,_]之外的字符,或者以数字开头,又或者是InfluxQL关键字,那么它们必须使用双引号。虽然并不总是需要,但是我们建议您为标识符加上双引号。
注释:这里关于引号的语法与行协议中的不同。
示例查询
查询单个measurement中的所有field和tag
1 | SELECT * FROM "h2o_feet" |
查询单个measurement中的特定的field和tag
1 | SELECT "level description","location","water_level" FROM "h2o_feet" |
查询单个measurement中的带标识符类型的特定的field和tag
1 | SELECT "level description"::field,"location"::tag,"water_level"::field FROM "h2o_feet" |
查询单个measurement中的所有field
1 | SELECT *::field FROM "h2o_feet" |
查询单个measurement中的特定的field并进行基本运算
1 | SELECT ("water_level" * 2) + 4 from "h2o_feet" |
查询多个measurement中的所有数据
1 | SELECT * FROM "h2o_feet","h2o_pH" |
查询完全限定的measurement中的所有数据
1 | SELECT * FROM "NOAA_water_database"."autogen"."h2o_feet" |
查询特定数据库的measurement中的所有数据
1 | SELECT * FROM "NOAA_water_database".."h2o_feet" |
SELECT语句常见的问题
在SELECT
子句中查询tag key
一个查询在SELECT
子句中必须至少包含一个field key才能返回结果。如果SELECT
子句中只包含一个或多个tag key,那么该查询会返回一个空的结果。这种返回结果的要求是系统存储数据的方式导致的。
如:
1 | SELECT "location" FROM "h2o_feet" |
这个不会返回任何数据
想要返回跟tag key location
相关的数据,查询中的SELECT
子句必须至少包含一个field key(water_level
):
1 | SELECT "water_level","location" FROM "h2o_feet" LIMIT 3 |
WHERE语句
1 | SELECT_clause FROM_clause WHERE <conditional_expression> [(AND|OR) <conditional_expression> [...]] |
语法
1 | field_key <operator> ['string' | boolean | float | integer] |
WHERE
子句支持对field value进行比较,field value可以是字符串、布尔值、浮点数或者整数。
在WHERE
子句中,请对字符串类型的field value用单引号括起来。如果字符串类型的field value没有使用引号或者使用了双引号,那么不会返回任何查询结果,在大多数情况下,也不会返回错误。
支持的操作符:
= | 等于 |
---|---|
<> | 不等于 |
!= | 不等于 |
> | 大于 |
>= | 大于或等于 |
< | 小于 |
<= | 小于或等于 |
tag
1 | tag_key <operator> ['tag_value'] |
在WHERE
子句中,请对tag value用单引号括起来。如果tag value没有使用引号或者使用了双引号,那么不会返回任何查询结果,在大多数情况下,也不会返回错误。
支持的操作符:
= | 等于 |
---|---|
<> | 不等于 |
!= | 不等于 |
timestamp
对于大多数SELECT
语句,默认的时间范围是从1677-09-21 00:12:43.145224194 UTC
到2262-04-11T23:47:16.854775806Z UTC
。对于带GROUP BY time()
子句的SELECT
语句,默认的时间范围是从1677-09-21 00:12:43.145224194 UTC
到now()
。
本页面中的时间语法章节将详细介绍如何在WHERE子句中指定其它的时间范围。
示例查询
查询field value满足一定条件的数据
1 | SELECT * FROM "h2o_feet" WHERE "water_level" > 8 |
查询field value满足一定条件的数据(field value是字符串类型)
1 | SELECT * FROM "h2o_feet" WHERE "level description" = 'below 3 feet' |
查询field value满足一定条件的数据(WHERE
子句包含基本运算)
1 | SELECT * FROM "h2o_feet" WHERE "water_level" + 2 > 11.9 |
查询tag value满足一定条件的数据
1 | SELECT "water_level" FROM "h2o_feet" WHERE "location" = 'santa_monica' |
查询field value和tag value都满足一定条件的数据
1 | 查询field value和tag value都满足一定条件的数据 |
查询timestamp满足一定条件的数据
1 | SELECT * FROM "h2o_feet" WHERE time > now() - 7d |
WHERE子句的常见问题
WHERE
子句出现异常则没有结果返回
在大多数情况下,引起这个问题的原因是tag value或字符串类型的field value缺少单引号。如果tag value或字符串类型的field value没有使用引号或者使用了双引号,那么不会返回任何查询结果,在大多数情况下,也不会返回错误。
下面的代码块中,前两个查询分别尝试没有用引号或者尝试用双引号来指定tag value:santa_monica
,这两个查询不会返回任何结果。第三个查询使用了单引号将santa_monica
括起来(这是支持的语法),返回了预期的结果。
1 | SELECT "water_level" FROM "h2o_feet" WHERE "location" = santa_monica |
下面的代码块中,前两个查询分别尝试没有用引号或者尝试用双引号来指定字符串类型的field value:at or greater than 9 feet
。第一个查询返回错误,因为该field value包含空格。第二个查询没有返回任何结果。第三个查询使用了单引号将at or greater than 9 feet
括起来(这是支持的语法),返回了预期的结果。
1 | SELECT "level description" FROM "h2o_feet" WHERE "level description" = at or greater than 9 feet |
GROUP BY子句
1 | SELECT_clause FROM_clause [WHERE_clause] GROUP BY [* | <tag_key>[,<tag_key]] |
语法描述
GROUP BY *
按所有tag对查询结果进行分组。
GROUP BY <tag_key>
按指定的一个tag对查询结果进行分组。
GROUP BY <tag_key>,<tag_key>
按多个tag对查询结果进行分组,tag key的顺序对结果无影响。
如果查询语句中包含一个WHERE
子句,那么GROUP BY
子句必须放在该WHERE
子句后面。
除此之外,GROUP BY
子句还支持的功能:正则表达式。
示例查询
按单个tag对查询结果进行分组
1 | SELECT MEAN("water_level") FROM "h2o_feet" GROUP BY "location" |
按多个tag对查询结果进行分组
1 | SELECT MEAN("index") FROM "h2o_quality" GROUP BY location,randtag |
按所有tag对查询结果进行分组
1 | SELECT MEAN("index") FROM "h2o_quality" GROUP BY * |
GROUP BY time intervals
GROUP BY time()
按用户指定的时间间隔对查询结果进行分组。
1 | SELECT <function>(<field_key>) FROM_clause WHERE <time_range> GROUP BY time(<time_interval>),[tag_key] [fill(<fill_option>)] |
语法描述
基本的GROUP BY time()
查询需要在SELECT
子句中包含一个InfluxQL函数,并且在WHERE
子句中包含时间范围。请注意,GROUP BY
子句必须放在WHERE
子句后面。
time(time_interval)
GROUP BY time()
子句中的time_interval
(时间间隔)是一个持续时间(duration),决定了TSDB For InfluxDB®按多大的时间间隔将查询结果进行分组。例如,当time_interval
为5m
时,那么在WHERE
子句中指定的时间范围内,将查询结果按5分钟进行分组。
Group By time() 的高级使用:
1
2
3
4 SELECT <function>(<field_key>)
FROM_clause
WHERE <time_range>
ROUP BY time(<time_interval>,<offset_interval>),[tag_key] [fill(<fill_option>)]
time(time_interval,offset_interval): 在GROUP BY time()子句中的通过time_interval和offset_interval来表示一个连续的时间区间,该时间区间决定了InfluxDB如何通过时间来对查询结果进行分组。比如,如果时间区间为5m,那么它会将查询结果分为5分钟一组(如果在WHERE子句中指定了time区间,那么就是将WHERE中指定的time区间划分为没5分钟一组)。offset_interval 是持续时间文本。它向前或向后移动InfluxDB数据库的预设时间边界。offset_interval 可以为正或负。
fill()是可选的。 它可以填充那些没有数据的时间区间的值。
fill()
fill()
是可选的,它会改变不含数据的时间间隔的返回值。
- 任何数学数值
使用给定的数学数值进行填充- linear
为没有数据值的时间区间线性插入数值,使得插入之后的数值,跟其他本来就有数据的区间的值成线性。(这里翻译的不是很好,看示例就能明白了)- none
若某个时间区间内没有数据,则在查询结果中该区间对应的时间戳将不显示出来- null
没有值的区间,显示为null。这也是默认的选项。- previous
用前一个区间的数值来填充当前没有数据的区间的值。
覆盖范围
基本的GROUP BY time()
查询依赖time_interval
和TSDB For InfluxDB®的预设时间边界来确定每个时间间隔内的原始数据和查询返回的时间戳。
语法示例
1 | SELECT "water_level","location" FROM "h2o_feet" WHERE time >= '2015-08-18T00:00:00Z' AND time <= '2015-08-18T00:30:00Z' |
将查询结果按12分钟的时间间隔进行分组
1 | SELECT COUNT("water_level") FROM "h2o_feet" WHERE "location"='coyote_creek' AND time >= '2015-08-18T00:00:00Z' AND time <= '2015-08-18T00:30:00Z' GROUP BY time(12m) |
将查询结果按12分钟的时间间隔和一个tag key进行分组
1 | SELECT COUNT("water_level") FROM "h2o_feet" WHERE time >= '2015-08-18T00:00:00Z' AND time <= '2015-08-18T00:30:00Z' GROUP BY time(12m),"location" |
基本语法的常见问题
查询结果中出现意想不到的时间戳和值
使用基本语法,TSDB For InfluxDB®依赖GROUP BY time()
中的时间间隔和系统的预设时间边界来确定每个时间间隔内的原始数据和查询返回的时间戳。在某些情况下,这可能会导致意想不到的结果。