RANGE QUERY
查询并聚合一个给定长度的时间范围的数据是时序数据常见的一种查询模式,例如 PromQL 中的 Range selector。而 GreptimeDB 在 SQL 中支持了 Range 查询,用于将时序数据汇总为时间块,并在时间块上进行数据的聚合。Range 查询作为 SELECT 语句的一部分,可与 SQL 灵活结合,从而在 SQL 中提供更强大的时序数据查询能力。
Syntax
Range query 使用 Time Index 列作为聚合的时间线。
一个合法的 Range 查询语法结构如下所示:
SELECT
AGGR_FUNCTION(column1, column2,..) RANGE INTERVAL [FILL FILL_OPTION],
...
FROM table_name
[ WHERE <where_clause>]
ALIGN INTERVAL [ TO TO_OPTION ] [BY (columna, columnb,..)] [FILL FILL_OPTION]
[ ORDER BY <order_by_clause>]
[ LIMIT <limit_clause>];
INTERVAL := TIME_INTERVAL | ( INTERVAL expr )
- 关键字
ALIGN,必选字段,后接参数INTERVAL,ALIGN指明了 Range 查询的步长。 - 参数
INTERVAL,主要用于给出一段时间长度,有两种参数形式:- 基于
PromQL Time Durations格式的字符串(例如:3h、1h30m)。访问 Prometheus 文档 获取该格式更详细的说明。 Interval类型,使用Interval类型需要携带括号,(例如:('1 year 3 hours 20 minutes'::INTERVAL))。访问 Interval 获取该格式更详细的说明。
- 基于
AGGR_FUNCTION(column1, column2,..) RANGE INTERVAL [FILL FILL_OPTION]称为一个 Range 表达式。AGGR_FUNCTION(column1, column2,..)是一个聚合函数,代表需要聚合的表达式。- 关键字
RANGE,必选字段,后接参数INTERVAL指定了每次数据聚合的时间范围, - 关键字
FILL,可选字段,详情请见FILLOption。 - Range 表达式可与其他运算结合,实现更复杂的查询。具体见嵌套使用 Range 表达式 。
- 关键字
FILL,可以跟在一个 Range 表达式后,详情请见FILL Option 。
FILL 选项
FILL 选项指定了在某个聚合的时间片上没有数据,或者聚合字段的值为空时的数据填充方法。
它可以跟在一个 Range 表达式后,作为这个 Range 表达式的数据填充方法;也可以放在 ALIGN 后面作为所有未指定 FILL 选项的 Range 表达式的填充方法。
例如,在下面的 SQL 代码中,
max(val) RANGE '10s' 范围表达式使用 FILL 选项 LINEAR,而 min(val) RANGE '10s' 没有指定 FILL 选项,它将使用在 ALIGN关键字之后指定的选项PREV。
SELECT
ts,
host,
min(val) RANGE '10s',
max(val) RANGE '10s' FILL LINEAR
FROM host_cpu
ALIGN '5s' BY (host) FILL PREV;
FILL 有以下几种选项:
| FILL | 描述 |
|---|---|
NULL | 直接使用 NULL 填充 |
PREV | 使用前一个点的数据填充 |
LINEAR | 使用线性插值法填充数据,如果一个整数类型使用 LINEAR 填充,则该列的变量类型会在计算的时候被隐式转换为浮点类型 |
X | 填充一个常量,该常量的数据类型必须和 Range 表达式的变量类型一致 |
以下面这张表为例
DROP TABLE IF EXISTS host_val;
CREATE TABLE host_val (
ts TIMESTAMP TIME INDEX,
host STRING,
val DOUBLE,
PRIMARY KEY (host)
);
INSERT INTO host_val VALUES
('1970-01-01 00:00:00', 'host1', 0),
('1970-01-01 00:00:15', 'host1', 6),
('1970-01-01 00:00:00', 'host2', 6),
('1970-01-01 00:00:15', 'host2', 12);
+---------------------+-------+------+
| ts | host | val |
+---------------------+-------+------+
| 1970-01-01 00:00:00 | host1 | 0 |
| 1970-01-01 00:00:15 | host1 | 6 |
| 1970-01-01 00:00:00 | host2 | 6 |
| 1970-01-01 00:00:15 | host2 | 12 |
+---------------------+-------+------+
不同 FILL 选项的结果如下:
- NO FILL
- FILL NULL
- FILL PREV
- FILL LINEAR
- FILL Constant Value 6.0
SELECT ts, host, min(val) RANGE '5s' FROM host_val ALIGN '5s';
+---------------------+-------+----------------------------+
| ts | host | min(host_val.val) RANGE 5s |
+---------------------+-------+----------------------------+
| 1970-01-01 00:00:00 | host1 | 0 |
| 1970-01-01 00:00:15 | host1 | 6 |
| 1970-01-01 00:00:00 | host2 | 6 |
| 1970-01-01 00:00:15 | host2 | 12 |
+---------------------+-------+----------------------------+
SELECT ts, host, min(val) RANGE '5s' FILL NULL FROM host_val ALIGN '5s';