Timescale Cloud:性能、扩展性、企业级

自托管产品

MST

函数管道是一项实验性功能,旨在彻底改进您在 PostgreSQL 和 SQL 中编写查询以分析数据的方式。它们通过应用函数式编程和流行工具(如 Python Pandas 和 PromQL)的原理来工作。

警告

实验性功能可能存在 bug。它们可能不向后兼容,并可能在未来的版本中被移除。请自行承担使用这些功能的风险,请勿在生产环境中使用任何实验性功能。

重要提示

timevector() 函数将其所有数据点实例化到内存中。这意味着,如果您在非常大的数据集上使用它,它可能会耗尽内存。请勿在大型数据集或生产环境中使用 timevector 函数。

SQL 是数据分析的最佳语言,但它并不完美,有时很难构建您想要的查询。例如,此查询从 measurements 表中获取过去一天的数据,按时间列对数据进行排序,计算值之间的增量,取增量的绝对值,然后对前述步骤的结果求和。

SELECT device id,
sum(abs_delta) as volatility
FROM (
SELECT device_id,
abs(val - lag(val) OVER last_day) as abs_delta
FROM measurements
WHERE ts >= now()-'1 day'::interval) calc_delta
GROUP BY device_id;

您可以使用如下函数管道来表达相同的查询:

SELECT device_id,
toolkit_experimental.timevector(ts, val)
-> toolkit_experimental.sort()
-> toolkit_experimental.delta()
-> toolkit_experimental.abs()
-> toolkit_experimental.sum() as volatility
FROM measurements
WHERE ts >= now()-'1 day'::interval
GROUP BY device_id;

函数管道完全符合 SQL 标准,这意味着任何支持 SQL 的工具都能够支持使用函数管道进行数据分析。

函数管道由一系列协同工作的元素构建而成,用于创建您的查询。管道最重要的部分是一种名为 timevector 的自定义数据类型。其他元素则作用于 timevector,通过使用自定义运算符来定义元素的运行顺序,从而构建您的查询。

timevector 是一个由时间-值对组成的集合,具有明确的开始时间和结束时间,看起来可能像这样:

An example timevector

您的整个数据库可能包含大量时间-值对,它们可以追溯到过去并延伸到未来,但 timevector 在该数据集中具有明确的开始和结束时间,看起来可能像这样:

An example of a timevector within a larger dataset

要从数据构建 timevector,请使用自定义聚合,并传入列以作为时间-值对。它使用 WHERE 子句定义子集的限制,并使用 GROUP BY 子句提供有关时间序列的识别信息。例如,要从包含温度的数据集中构建 timevector,SQL 如下所示:

SELECT device_id,
toolkit_experimental.timevector(ts, val)
FROM measurements
WHERE ts >= now() - '1 day'::interval
GROUP BY device_id;

函数管道使用单个自定义运算符 ->。此运算符用于应用和组合多个函数。-> 运算符接收运算符左侧的输入,并应用运算符右侧的操作。更直白地说,您可以将其视为“执行下一个操作”。

一个典型的函数管道可能看起来像这样:

SELECT device_id,
toolkit_experimental.timevector(ts, val)
-> toolkit_experimental.sort()
-> toolkit_experimental.delta()
-> toolkit_experimental.abs()
-> toolkit_experimental.sum() as volatility
FROM measurements
WHERE ts >= now() - '1 day'::interval
GROUP BY device_id;

尽管乍一看 timevector(ts, val) 操作像是 sort() 的一个参数,但在管道中,这些都是常规的函数调用。每个调用都只能操作其自身括号内的内容,并且不了解语句中它们左侧的任何内容。

管道中的每个函数都返回一个自定义类型,描述该函数及其参数,这些都是管道元素。-> 运算符根据其左右两侧的类型执行两种不同类型的操作之一:

  • 将管道元素应用于左侧参数:直接对传入数据类型执行由管道元素描述的函数。
  • 将管道元素组合成一个可以在未来某个时间点应用的组合元素。这是一种优化,允许您嵌套元素以减少所需的遍历次数。

运算符根据其左右参数确定要执行的操作。

管道元素主要有两种类型:

  • 转换器(Transforms)改变 timevector 的内容,并返回更新后的向量。
  • 终结器(Finalizers)完成管道并输出结果数据。

转换元素接收 timevector 并生成 timevector。它们是最简单的组合元素,因为它们生成相同的类型。例如:

SELECT device_id,
toolkit_experimental.timevector(ts, val)
-> toolkit_experimental.sort()
-> toolkit_experimental.delta()
-> toolkit_experimental.map($$ ($value^3 + $value^2 + $value * 2) $$)
-> toolkit_experimental.lttb(100)
FROM measurements

终结器元素结束管道的 timevector 部分。它们可以以指定格式生成输出,也可以生成 timevector 的聚合。

例如,一个生成输出的终结器元素:

SELECT device_id,
toolkit_experimental.timevector(ts, val)
-> toolkit_experimental.sort()
-> toolkit_experimental.delta()
-> toolkit_experimental.unnest()
FROM measurements

或者一个生成聚合的终结器元素:

SELECT device_id,
toolkit_experimental.timevector(ts, val)
-> toolkit_experimental.sort()
-> toolkit_experimental.delta()
-> toolkit_experimental.time_weight()
FROM measurements

第三种管道元素是聚合访问器和修改器。这些在管道中作用于 timevector,但它们也适用于常规聚合查询。在管道中使用它们的示例:

SELECT percentile_agg(val) -> toolkit_experimental.approx_percentile(0.5)
FROM measurements

转换元素接收一个 timevector,并生成一个 timevector

向量化数学函数元素使用指定的数学函数修改 timevector 内的每个 value。它们逐点应用,并从输入到输出 timevector 生成一对一的映射。输入中的每个点在输出中都有一个对应的点,其 value 通过指定的数学函数进行转换。

元素总是从左到右应用,因此即使存在显式括号,也不会考虑操作顺序。这意味着对于 timevector('2020-01-01 00:00:00+00', 20.0),此管道有效:

timevector('2021-01-01 UTC', 10) -> add(5) -> (mul(2) -> add(1))

此管道也以相同方式工作:

timevector('2021-01-01 UTC', 10) -> add(5) -> mul(2) -> add(1)

这两个示例都生成 ('2020-01-01 00:00:00+00', 31.0)

如果需要多个算术操作且优先级很重要,请考虑改用 Lambda

一元数学函数元素将相应的数学函数应用于 timevector 中的每个数据点,保持时间戳和顺序不变。可用的元素有:

元素描述
abs()计算每个值的绝对值
cbrt()计算每个值的立方根
ceil()计算每个值的大于或等于它的最小整数
floor()计算每个值的小于或等于它的最大整数
ln()计算每个值的自然对数
log10()计算每个值的以 10 为底的对数
round()计算每个值最接近的整数
sign()计算每个正/负值的 +/-1
sqrt()计算每个值的平方根
trunc()仅计算每个值的整数部分

即使元素逻辑上计算出整数,timevector 也只处理双精度浮点值,因此计算出的值是整数的浮点表示。例如:

-- NOTE: the (pipeline -> unnest()).* allows for time, value columns to be produced without a subselect
SELECT (
toolkit_experimental.timevector(time, value)
-> toolkit_experimental.abs()
-> toolkit_experimental.unnest()).*
FROM (VALUES (TimestampTZ '2021-01-06 UTC', 0.0 ),
( '2021-01-01 UTC', 25.0 ),
( '2021-01-02 UTC', 0.10),
( '2021-01-04 UTC', -10.0 ),
( '2021-01-05 UTC', 3.3 )
) as v(time, value);

此示例的输出:

time | value
------------------------+-------
2021-01-06 00:00:00+00 | 0
2021-01-01 00:00:00+00 | 25
2021-01-02 00:00:00+00 | 0.1
2021-01-04 00:00:00+00 | 10
2021-01-05 00:00:00+00 | 3.3
(5 rows)

二元数学函数元素对 timevector 中每个点的值运行相应的数学函数,使用提供的数字作为函数的第二个参数。可用的元素有:

元素描述
add(N)计算每个值加上 N
div(N)计算每个值除以 N
logn(N)计算每个值的以 N 为底的对数
mod(N)计算每个数除以 N 时的余数
mul(N)计算每个值乘以 N
power(N)计算每个值的 N 次幂
sub(N)计算每个值减去 N

这些元素通过对所有 values 进行平方来计算 vector -> power(2),而 vector -> logn(3) 则给出每个 value 的以 3 为底的对数。例如:

SELECT (
toolkit_experimental.timevector(time, value)
-> toolkit_experimental.power(2)
-> toolkit_experimental.unnest()).*
FROM (VALUES (TimestampTZ '2021-01-06 UTC', 0.0 ),
( '2021-01-01 UTC', 25.0 ),
( '2021-01-02 UTC', 0.10),
( '2021-01-04 UTC', -10.0 ),
( '2021-01-05 UTC', 3.3 )
) as v(time, value);

此示例的输出:

time | value
------------------------+----------------------
2021-01-06 00:00:00+00 | 0
2021-01-01 00:00:00+00 | 625
2021-01-02 00:00:00+00 | 0.010000000000000002
2021-01-04 00:00:00+00 | 100
2021-01-05 00:00:00+00 | 10.889999999999999
(5 rows)

数学转换仅应用于 timevector 中每个点的值,并且总是生成一对一的输出 timevector。复合转换可以涉及 timevector 中点的时间和值部分,并且它们不一定是一对一的。输入中的一个或多个点可以用于生成输出中的零个或多个点。因此,当数学转换总是生成相同长度的 timevector 时,复合转换可以生成更大或更小的 timevector 作为输出。

delta() 转换计算 timevector 中连续 values 之间的差异。timevector 中的第一个点被省略,因为没有前一个值,因此无法计算 delta()。数据应在使用 delta() 之前使用 sort() 元素进行排序。例如:

SELECT (
toolkit_experimental.timevector(time, value)
-> toolkit_experimental.sort()
-> toolkit_experimental.delta()
-> toolkit_experimental.unnest()).*
FROM (VALUES (TimestampTZ '2021-01-06 UTC', 0.0 ),
( '2021-01-01 UTC', 25.0 ),
( '2021-01-02 UTC', 0.10),
( '2021-01-04 UTC', -10.0 ),
( '2021-01-05 UTC', 3.3 )
) as v(time, value);

此示例的输出:

time | value
------------------------+-------
2021-01-02 00:00:00+00 | -24.9
2021-01-04 00:00:00+00 | -10.1
2021-01-05 00:00:00+00 | 13.3
2021-01-06 00:00:00+00 | -3.3
(4 rows)
注意

输出的第一行缺失,因为没有前一个值无法计算增量。

fill_to() 转换确保每隔一个 interval 至少有一个点,如果没有,则使用提供的方法填充该点。在调用 fill_to() 之前,timevector 必须是已排序的。可用的填充方法有:

填充方法描述
LOCF最后已知值前向填充,用缺失点之前的最后一个已知值填充
插值使用与两侧第一个已知值共线的点填充缺失部分
线性这是插值的别名
最近用缺失点之前或之后更近点的匹配值填充

例如:

SELECT (
toolkit_experimental.timevector(time, value)
-> toolkit_experimental.sort()
-> toolkit_experimental.fill_to('1 day', 'LOCF')
-> toolkit_experimental.unnest()).*
FROM (VALUES (TimestampTZ '2021-01-06 UTC', 0.0 ),
( '2021-01-01 UTC', 25.0 ),
( '2021-01-02 UTC', 0.10),
( '2021-01-04 UTC', -10.0 ),
( '2021-01-05 UTC', 3.3 )
) as v(time, value);

此示例的输出:

time | value
------------------------+-------
2021-01-01 00:00:00+00 | 25
2021-01-02 00:00:00+00 | 0.1
2021-01-03 00:00:00+00 | 0.1
2021-01-04 00:00:00+00 | -10
2021-01-05 00:00:00+00 | 3.3
2021-01-06 00:00:00+00 | 0
(6 rows)

最大三角形三桶 (LTTB) 转换使用 LTTB 图形降采样算法将 timevector 降采样到指定分辨率,同时保持视觉保真度。

sort() 转换按时间对 timevector 进行升序排序。如果 timevector 已排序,则此转换被忽略。例如:

SELECT (
toolkit_experimental.timevector(time, value)
-> toolkit_experimental.sort()
-> toolkit_experimental.unnest()).*
FROM (VALUES (TimestampTZ '2021-01-06 UTC', 0.0 ),
( '2021-01-01 UTC', 25.0 ),
( '2021-01-02 UTC', 0.10),
( '2021-01-04 UTC', -10.0 ),
( '2021-01-05 UTC', 3.3 )
) as v(time, value);

此示例的输出:

time | value
------------------------+-------
2021-01-01 00:00:00+00 | 25
2021-01-02 00:00:00+00 | 0.1
2021-01-04 00:00:00+00 | -10
2021-01-05 00:00:00+00 | 3.3
2021-01-06 00:00:00+00 | 0
(5 rows)

Lambda 元素函数使用工具包的实验性 Lambda 语法来转换 timevector。Lambda 是一个应用于 timevector 元素的表达式。它通常以 $$ 引用字符串的形式编写,其中包含要运行的表达式。例如:

$$
let $is_relevant = $time > '2021-01-01't and $time < '2021-10-14't;
let $is_significant = abs(round($value)) >= 0;
$is_relevant and $is_significant
$$

Lambda 表达式可以使用以下组件构建:

  • 变量声明,例如 let $foo = 3; $foo * $foo。变量声明以分号结尾。所有 Lambda 必须以表达式结尾,表达式不带分号。多个变量声明可以相互跟随,例如:let $foo = 3; let $bar = $foo * $foo; $bar * 10
  • 变量名,例如 $foo。它们必须以 $ 符号开头。变量 $time$value 是保留的;它们指代 Lambda 表达式被调用的向量中点的时间和值。
  • 函数调用,例如 abs($foo)。支持大多数数学函数。
  • 支持包含算术二元运算符 andor=!=<<=>>=^*/+-二元操作
  • 间隔字面量以尾随的 i 表示。例如,'1 day'i。除了尾随的 i,它们遵循 PostgreSQL INTERVAL 输入格式。
  • 时间字面量,例如 '2021-01-02 03:00:00't,以尾随的 t 表示。除了尾随的 t,它们遵循 PostgreSQL TIMESTAMPTZ 输入格式。
  • 数字字面量,例如 420.0-71e2

Lambda 遵循的语法大致相当于 EBNF。例如:

Expr = ('let' Variable '=' Tuple ';')* Tuple
Tuple = Binops (',' Binops)*
Binops = Unaryops (Binop Unaryops)*
UnaryOps = ('-' | 'not') UnaryOps | Term
Term = Variable | Time | Interval | Number | Function | '(' Expr ')'
Function = FunctionName '(' (Binops ',')* ')'
Variable = ? described above ?
Time = ? described above ?
Interval = ? described above ?
Number = ? described above ?

map() Lambda 映射 timevector 的每个元素。此 Lambda 必须返回 DOUBLE PRECISION(仅更改 timevector 中每个点的值)或 (TIMESTAMPTZ, DOUBLE PRECISION)(同时更改时间和值)。一个返回 DOUBLE PRECISIONmap() Lambda 示例:

SELECT (
toolkit_experimental.timevector(time, value)
-> toolkit_experimental.map($$ $value + 1 $$)
-> toolkit_experimental.unnest()).*
FROM (VALUES (TimestampTZ '2021-01-06 UTC', 0.0 ),
( '2021-01-01 UTC', 25.0 ),
( '2021-01-02 UTC', 0.10),
( '2021-01-04 UTC', -10.0 ),
( '2021-01-05 UTC', 3.3 )
) as v(time, value);

此示例的输出:

time | value
------------------------+-------
2021-01-06 00:00:00+00 | 1
2021-01-01 00:00:00+00 | 26
2021-01-02 00:00:00+00 | 1.1
2021-01-04 00:00:00+00 | -9
2021-01-05 00:00:00+00 | 4.3
(5 rows)

一个返回 (TIMESTAMPTZ, DOUBLE PRECISION)map() Lambda 示例:

SELECT (
toolkit_experimental.timevector(time, value)
-> toolkit_experimental.map($$ ($time + '1day'i, $value * 2) $$)
-> toolkit_experimental.unnest()).*
FROM (VALUES (TimestampTZ '2021-01-06 UTC', 0.0 ),
( '2021-01-01 UTC', 25.0 ),
( '2021-01-02 UTC', 0.10),
( '2021-01-04 UTC', -10.0 ),
( '2021-01-05 UTC', 3.3 )
) as v(time, value);

此示例的输出:

time | value
------------------------+-------
2021-01-07 00:00:00+00 | 0
2021-01-02 00:00:00+00 | 50
2021-01-03 00:00:00+00 | 0.2
2021-01-05 00:00:00+00 | -20
2021-01-06 00:00:00+00 | 6.6
(5 rows)

filter() Lambda 根据 Lambda 表达式过滤 timevector,对于应保留在 timevector 时间序列中的每个点返回 true,对于应删除的每个点返回 false。例如:

SELECT (
toolkit_experimental.timevector(time, value)
-> toolkit_experimental.filter($$ $time != '2021-01-01't AND $value > 0 $$)
-> toolkit_experimental.unnest()).*
FROM (VALUES (TimestampTZ '2021-01-06 UTC', 0.0 ),
( '2021-01-01 UTC', 25.0 ),
( '2021-01-02 UTC', 0.10),
( '2021-01-04 UTC', -10.0 ),
( '2021-01-05 UTC', 3.3 )
) as v(time, value);

此示例的输出:

time | value
------------------------+-------
2021-01-02 00:00:00+00 | 0.1
2021-01-05 00:00:00+00 | 3.3
(2 rows)

终结器元素完成函数管道,并输出一个值或一个聚合。

您可以使用 timevector 输出元素来终结管道。这些元素用于管道的末端,以返回一个 timevector。如果您以后需要在另一个管道中使用它们,这会很有用。两种输出类型是:

  • unnest(),它返回一组 (TimestampTZ, DOUBLE PRECISION) 对。
  • materialize(),它强制管道实例化一个 timevector。这会阻止任何惰性实例化 timevector 的优化。

这些元素接收一个 timevector,并对其运行相应的聚合以生成结果。可能的元素有:

  • average()
  • integral()
  • counter_agg()
  • hyperloglog()
  • stats_agg()
  • sum()
  • num_vals()

使用 num_vals() 的聚合输出示例:

SELECT toolkit_experimental.timevector(time, value) -> toolkit_experimental.num_vals()
FROM (VALUES (TimestampTZ '2021-01-06 UTC', 0.0 ),
( '2021-01-01 UTC', 25.0 ),
( '2021-01-02 UTC', 0.10),
( '2021-01-04 UTC', -10.0 ),
( '2021-01-05 UTC', 3.3 )
) as v(time, value);

此示例的输出:

?column?
----------
5
(1 row)

使用 stats_agg() 的聚合输出示例:

SELECT
toolkit_experimental.timevector(time, value)
-> toolkit_experimental.stats_agg()
-> toolkit_experimental.stddev()
FROM (VALUES (TimestampTZ '2021-01-06 UTC', 0.0 ),
( '2021-01-01 UTC', 25.0 ),
( '2021-01-02 UTC', 0.10),
( '2021-01-04 UTC', -10.0 ),
( '2021-01-05 UTC', 3.3 )
) as v(time, value);

此示例的输出:

?column?
--------------------
12.924666339987272
(1 row)

聚合访问器和修改器在函数管道中的工作方式与在其他聚合中的工作方式相同。您可以使用它们从函数管道的聚合部分获取值。例如:

SELECT device_id,
timevector(ts, val) -> sort() -> delta() -> stats_agg() -> variance()
FROM measurements

当您在管道中使用它们而不是标准函数访问器和修改器时,它们可以通过消除嵌套函数来使语法更清晰。例如,嵌套语法如下所示:

SELECT approx_percentile(0.5, percentile_agg(val))
FROM measurements

改用带有 -> 运算符的函数管道看起来像这样:

SELECT percentile_agg(val) -> approx_percentile(0.5)
FROM measurements

计数器聚合处理重置计数器。计数器是应用程序性能监控和指标中常见的指标类型。所有值都考虑了重置。这些元素在管道中使用时,必须在其左侧有一个 CounterSummary,来自 counter_agg() 聚合或管道元素。可用的计数器聚合函数有:

元素描述
counter_zero_time()根据输入到 CounterSummary(x 截距)的点的最小二乘拟合,预测计数器值为零的时间
corr()调整后计数器值的最小二乘拟合线的相关系数
delta()计算计数器的最后一个值减去第一个值
extrapolated_delta(method)使用提供的方法将增量外推到范围边界。边界必须已在聚合或 with_bounds 调用中提供。
idelta_left()/idelta_right()计算第二个点和第一个点(左侧)或最后一个点和倒数第二个点(右侧)之间的瞬时差值
intercept()调整后计数器值的最小二乘拟合线的 y 截距
irate_left()/irate_right()计算第二个点和第一个点(左侧)或最后一个点和倒数第二个点(右侧)之间的瞬时变化率
num_changes()计数器值改变的次数
num_elements()项目数量 - 任何具有完全相同时间的只计数一次
num_changes()计数器重置的次数
slope()调整后计数器值的最小二乘拟合线的斜率
with_bounds(range)如果未在聚合步骤中提供范围,则使用 range(一个 TSTZRANGE)将边界应用于 CounterSummary

百分位近似聚合访问器用于近似百分位。目前,仅为基于 percentile_agguddsketch 的聚合实现了访问器。我们尚未实现使用 tdigest 进行百分位近似的管道聚合。

元素描述
approx_percentile(p)在百分位 p 处的近似值
approx_percentile_rank(v)v 所处的近似百分位
error()近似保证的最大相对误差
mean()输入值的精确平均值。
num_vals()输入值的数量

统计聚合访问器增加了对常见统计聚合的支持。这些允许您计算和 rollup() 常见的统计聚合(如 averagestddev)、更高级的聚合(如 skewness)以及二维聚合(如 slopecovariance)。因为这些聚合既有单维版本也有二维版本,所以访问器可以有多种形式。例如,average() 在单维聚合上计算平均值,而 average_y()average_x() 则在两个维度上分别计算平均值。可用的统计聚合有:

元素描述
average()/average_y()/average_x()值的平均值
corr()最小二乘拟合线的相关系数
covariance(method)使用总体或样本方法计算值的协方差
determination_coeff()值的决定系数(或 R 平方)
kurtosis(method)/kurtosis_y(method)/kurtosis_x(method)使用总体或样本方法计算值的峰度(四阶矩)
intercept()最小二乘拟合线的截距
num_vals()已观测值的数量
skewness(method)/skewness_y(method)/skewness_x(method)使用总体或样本方法计算值的偏度(三阶矩)
slope()最小二乘拟合线的斜率
stddev(method)/stddev_y(method)/stddev_x(method)使用总体或样本方法计算值的标准差
sum()值的总和
variance(method)/variance_y(method)/variance_x(method)使用总体或样本方法计算值的方差
x_intercept()最小二乘拟合线的 x 截距

average() 访问器可以在 time_weight() 的输出上调用。例如:

SELECT time_weight('Linear', ts, val) -> average() FROM measurements;

这是对去重计数的近似。distinct_count() 访问器可以在 hyperloglog() 的输出上调用。例如:

SELECT hyperloglog(device_id) -> distinct_count() FROM measurements;

您可以将 timevector 转换为格式化的文本表示。将 timevector 转换为文本有两种函数:

toolkit_experimental.to_text(
timevector(time, value),
format_string
)

此函数根据 format_string 生成文本表示。格式字符串可以使用任何有效的 Tera 模板语法,并且可以包含任何内置变量:

  • TIMEStimevector 中的所有时间,以数组形式表示
  • VALUEStimevector 中的所有值,以数组形式表示
  • TIMEVALStimevector 中的所有时间-值对,格式为 {"time": $TIME, "val": $VAL},以数组形式表示

例如,给定此数据表:

CREATE TABLE data(time TIMESTAMPTZ, value DOUBLE PRECISION);
INSERT INTO data VALUES
('2020-1-1', 30.0),
('2020-1-2', 45.0),
('2020-1-3', NULL),
('2020-1-4', 55.5),
('2020-1-5', 10.0);

您可以使用带有 TIMEVALS 的格式字符串生成以下文本:

SELECT toolkit_experimental.to_text(
timevector(time, value),
'{{TIMEVALS}}'
) FROM data;
[{\"time\": \"2020-01-01 00:00:00+00\", \"val\": 30}, {\"time\": \"2020-01-02 00:00:00+00\", \"val\": 45}, {\"time\": \"2020-01-03 00:00:00+00\", \"val\": null}, {\"time\": \"2020-01-04 00:00:00+00\", \"val\": 55.5}, {\"time\": \"2020-01-05 00:00:00+00\", \"val\": 10} ]

或者您可以使用带有 TIMESVALUES 的格式字符串生成以下文本:

SELECT toolkit_experimental.to_text(
timevector(time,value),
'{\"times\": {{ TIMES }}, \"vals\": {{ VALUES }}}'
) FROM data
{\"times\": [\"2020-01-01 00:00:00+00\",\"2020-01-02 00:00:00+00\",\"2020-01-03 00:00:00+00\",\"2020-01-04 00:00:00+00\",\"2020-01-05 00:00:00+00\"], \"vals\": [\"30\",\"45\",\"null\",\"55.5\",\"10\"]}

此函数生成适合与 Plotly 一起使用的文本表示。

例如,给定此数据表:

CREATE TABLE data(time TIMESTAMPTZ, value DOUBLE PRECISION);
INSERT INTO data VALUES
('2020-1-1', 30.0),
('2020-1-2', 45.0),
('2020-1-3', NULL),
('2020-1-4', 55.5),
('2020-1-5', 10.0);

您可以生成以下与 Plotly 兼容的文本:

SELECT toolkit_experimental.to_plotly(
timevector(time, value)
) FROM data;
{\"times\": [\"2020-01-01 00:00:00+00\",\"2020-01-02 00:00:00+00\",\"2020-01-03 00:00:00+00\",\"2020-01-04 00:00:00+00\",\"2020-01-05 00:00:00+00\"], \"vals\": [\"30\",\"45\",\"null\",\"55.5\",\"10\"]}

此表按字母顺序列出所有函数管道元素:

元素类别输出
abs()一元数学timevector 管道
add(val DOUBLE PRECISION)二元数学timevector 管道
average()聚合终结器DOUBLE PRECISION
cbrt()一元数学timevector 管道
ceil()一元数学timevector 管道
counter_agg()聚合终结器CounterAgg
delta()复合timevector 管道
div二元数学timevector 管道
fill_to复合timevector 管道
filterLambdatimevector 管道
floor一元数学timevector 管道
hyperloglog聚合终结器HyperLogLog
ln一元数学timevector 管道
log10一元数学timevector 管道
logn二元数学timevector 管道
lttb复合timevector 管道
mapLambdatimevector 管道
materialize输出timevector 管道
mod二元数学timevector 管道
mul二元数学timevector 管道
num_vals聚合终结器BIGINT
power二元数学timevector 管道
round一元数学timevector 管道
sign一元数学timevector 管道
sort复合timevector 管道
sqrt一元数学timevector 管道
stats_agg聚合终结器StatsSummary1D
sub二元数学timevector 管道
sum聚合终结器timevector 管道
trunc一元数学timevector 管道
unnest输出TABLE (time TIMESTAMPTZ, value DOUBLE PRECISION)

关键词

在此页面上发现问题?报告问题 或在 GitHub 上编辑此页面