目录
- 为什么正确的工具在分析时间序列数据时很重要
- 认识 Hyperfunctions
- 解决方案:如何使用date_trunc查询任意时间间隔
- Simpler Time-Weighted Averages
- 使用Percentile Approximation做数据汇总
- first( ) 和 last( )
- 使用COUNT DISTINCT查询,发挥内存效率
- 通过使用Function Pipelines增强查询可读性和维护
- 通过频率聚合简化频率分析
- 立即通过使用Hyperfunctions提高您的工作效率
1、为什么正确的工具在分析时间序列数据时很重要
SQL是分析的通用语言。 随着数据的激增,我们需要找到新的方法来存储、探索和分析数据。我们相信SQL是数据分析的最佳语言。几年来,我们一直倡导SQL的优势,即使许多人将其替换为domain-specific语言。完全的SQL支持是我们选择在开发人员最喜欢的数据库PostgreSQL之上构建TimescaleDB的关键原因之一,而不是创建自定义查询语言。我们是对的——–SQL正在卷土重来(尽管它从未真正消失过),并已成为数据分析的通用语言,许多NoSQL数据库都添加了SQL接口来跟上。
此外,大多数开发人员都熟悉 SQL,以及大多数数据科学家、数据分析师和其他处理数据的专业人员。无论您是在大学上过课,完成在线课程还是参加过训练营,您都可能在此过程中学习了一些SQL。因此,您和您的开发人员同事已经知道这一点,使团队更容易加入新成员并从数据中提取价值。使用专有语言,学习该语言本身就是使用数据的障碍 - 您必须要求另一个团队编写查询或依赖单独的数据湖。
时间序列数据无处不在。 在Timescale,我们的使命是为全球开发人员提供服务,使他们能够构建卓越的数据驱动型产品,以衡量所有重要因素:软件应用程序,工业设备,金融市场,区块链活动,用户行为,消费者行为,机器学习模型,气候变化等。
时间序列数据快速出现,有时每秒生成数百万个数据点。由于信息量和速度庞大,即使在 SQL 中,时序数据查询和分析起来也很复杂。
TimescaleDB hyperfunctions
使操作和分析时序数据集变得更加容易,只需较少的 SQL 代码行。hyperfunctions是专门为开发人员今天用SQL编写的最常见和最困难的时间序列和分析查询而构建的。使用hyperfunctions可以提高查询时序数据的工作效率,这意味着您可以花更少的时间创建涉及时间序列的报表、仪表板和可视化效果,并花更多时间根据工作挖掘的见解采取行动!
2、认识 Hyperfunctions
目前有超过70种不同的TimescaleDB Hyperfunctions可供使用。以下是一些最受欢迎的方法以及它们如何为您提供帮助:
-
基于时间的分析:使您能够使用简洁的查询在任意时间间隔内分析数据,从而使基于时间的分析更简单、更轻松。time_bucket() time_bucket_ng()
-
first() 和 last() 允许您按另一列的顺序获取一列的值(在 TimescaleDB 2.7 中快 2 倍!)
-
Time-weighted averages:以及用于处理time-weighted averages的相关hyperfunctions提供了一种更优雅的方式,可以在处理不规则采样的数据时获得无偏平均值。time_weight()
-
Function pipelines 使您能够通过组合多个函数来分析数据,从而在PostgreSQL中以更简单,更干净的方式表达复杂逻辑(目前是实验性的)。
-
Percentile approximation 将百分位数分析引入更多工作流,使您能够有效地了解数据的分布(例如,10%、50%、90% 等),而无需对庞大的时间序列数据集执行昂贵的计算。与连续聚合一起使用时,可以近乎实时地计算数据集的任何时间范围内的百分位数,并将它们用于基线和规范化传入数据。
-
频率分析:与暴力计算相比,相关的频率分析Hyperfunctions可以更有效地从一组变化更大的值中找到最常见的元素。Freq_agg()
-
直方图显示数据分布,与平均值相比,可以更好地理解段(更多关于直方图)。
-
缩减采样: “尽快”平滑化数据集,以在绘制图表时突出显示最重要的特征。最大三角形三个存储桶可对数据集中的元素数量进行缩减采样或减少,同时在绘制图表时保留重要要素。
了解如何在 Grafana 中应用我们的缩减采样Hyperfunctions。lttb() -
Memory efficient COUNT DISTINCTs:HyperLogLog 是一种概率基数估计器,与等效的 COUNT DISTINCT 查询相比,它使用的内存要少得多。它非常适合用于大型数据集的连续聚合。
我们为这些时间序列分析和操作功能中的每一个都创建了新的 SQL 函数。这与通过引入新的 SQL 语法来改善开发人员体验的其他努力形成鲜明对比。虽然从实现的角度来看,使用新的关键字和构造引入新的语法可能更容易,但我们故意决定不这样做,因为我们相信这会导致最终用户的体验更差。
新的 SQL 语法意味着现有的驱动程序、库和工具可能不再有效。这可能给开发人员带来比解决方案更多的问题,因为他们最喜欢的工具、库或驱动程序可能不支持新语法或需要耗时的修改。另一方面,新的 SQL 函数意味着您的查询将在每个可视化工具、数据库管理工具或数据分析工具中运行。
我们可以自由地创建自定义函数、聚合和过程,帮助开发人员更好地理解和使用他们的数据,并确保他们的所有驱动程序和接口仍然按预期工作!现在,我们将深入研究我们提到的每个Hyperfunctions类别,并举例说明何时、为何以及如何使用它们,以及继续学习的资源。
TimescaleDB Hyperfunctions已预先加载,并可在 Timescale Cloud 中的每个托管和托管数据库服务上使用,这是开始使用 TimescaleDB 的最简单方法。
3、解决方案:如何使用date_trunc查询任意时间间隔
使用 PostgreSQL 时,当您想要在一段时间内聚合信息时,该函数可能很有用。 根据指定的日期部分(例如,小时、周或月)截断或值,并返回截断的时间戳或间隔。例如,可以聚合一秒、一小时、一天或一周。但是,您通常希望按对您的用例最重要的时间间隔查看聚合,这些时间间隔可能是 30 秒、5 分钟、12 小时等间隔。这在SQL中可能会变得非常复杂,只需看看下面的查询,它以五分钟的时间间隔分析出租车活动: TIMESTAMP INTERVAL date_trunc
常规PostgreSQL:每五分钟乘坐出租车一次
SELECT
EXTRACT(hour from pickup_datetime) as hours,
trunc(EXTRACT(minute from pickup_datetime) / 5)*5 AS five_mins,
COUNT(*)
FROM rides
WHERE pickup_datetime < '2016-01-02 00:00'
GROUP BY hours, five_mins;
通过 Hyperfunctions,您可以轻松地在与分析用例最相关的任何时间间隔内查询数据。 使您能够按任意时间间隔(例如,10 秒、5 分钟、6 小时等)聚合数据,并为您提供灵活的分组和偏移量,而不仅仅是秒、分钟、小时等。time_bucket() time_bucket()
除了允许更灵活的时序查询外,还允许您以更简单的方式编写这些查询。只需从上面的例子中看一下,查询是编写和理解使用Hyperfunctions时要简单得多:time_bucket()
TimescaleDB Hyperfunctions:每五分钟乘坐出租车一次
-- How many rides took place every 5 minutes for the first day of 2016?
SELECT time_bucket('5 minute', pickup_datetime) AS five_min, count(*)
FROM rides
WHERE pickup_datetime < '2016-01-02 00:00'
GROUP BY five_min
ORDER BY five_min;
如果您希望在聚合数据时具有更大的灵活性,则可以测试实验性Hyperfunctions ,这是 Hyperfunctions的更新版本。 使您能够按年和月以及秒、分钟和小时时间间隔来存储数据。这使您可以轻松地在SQL中进行月度同期分析或其他基于多个月份的报告。time_bucket_ng()
SELECT timescaledb_experimental.time_bucket_ng('3 month', date '2021-08-01');
time_bucket_ng
----------------
2021-07-01
(1 row)
time_bucket_ng()还具有自定义时区支持,使您能够编写如下所示的查询,这说明了如何使用它来存储欧洲/莫斯科区域的数据:
-- note that timestamptz is displayed differently depending on the session parameters
SET TIME ZONE 'Europe/Moscow';
SELECT timescaledb_experimental.time_bucket_ng('1 month', timestamptz '2001-02-03 12:34:56 MSK', timezone => 'Europe/Moscow');
time_bucket_ng
------------------------
2001-02-01 00:00:00+03
在每秒或每分钟捕获数百或数千个时间序列读数时,通常会发生数据丢失或间隔的情况。这可能是由于不规则的采样间隔,或者您经历了某种中断。
Hyperfunctions
使您能够在任何间隔中创建其他数据行,确保返回的行按时间顺序排列且连续。
使用 SQL 函数进行时序分析。time_bucket_gapfill()
下面是一个操作示例,其中我们查找某个设备的每日平均温度,并在数据中存在空白的情况下使用该函数将最后一个观测值向前推进:time_bucket_gapfill() locf()
SELECT
time_bucket_gapfill('1 day', time, now() - INTERVAL '1 week', now()) AS day,
device_id,
avg(temperature) AS value,
locf(avg(temperature))
FROM metrics
WHERE time > now () - INTERVAL '1 week'
GROUP BY day, device_id
ORDER BY day;
day | device_id | value | locf
------------------------+-----------+-------+------
2019-01-10 01:00:00+01 | 1 | |
2019-01-11 01:00:00+01 | 1 | 5.0 | 5.0
2019-01-12 01:00:00+01 | 1 | | 5.0
2019-01-13 01:00:00+01 | 1 | 7.0 | 7.0
2019-01-14 01:00:00+01 | 1 | | 7.0
2019-01-15 01:00:00+01 | 1 | 8.0 | 8.0
2019-01-16 01:00:00+01 | 1 | 9.0 | 9.0
(7 rows)
最后一次观测值或函数允许您前转聚合组中最后一次看到的值。您只能在具有 的聚合查询中使用它。locf() time_bucket_gapfill()
要了解有关使用Hyperfunctions系列的更多信息,请阅读文档,并开始学习我们的教程,该教程用于分析真实的物联网数据集。 time_bucket()
4、Simpler Time-Weighted Averages
如果您处于没有定期采样数据的情况下,则在一段时间内获得具有代表性的平均值可能是一个复杂且耗时的查询。例如,在以下情况下经常发生不规则采样的数据,因此需要时间加权平均值:
-
工业物联网,团队通过在值变化时仅发送“压缩”数据。
遥感,从边缘发送数据的成本可能很高,因此您只能为最关键的操作发送高频数据。 -
基于触发器的系统,其中一个传感器的采样率受另一个传感器读数的影响(即,当运动传感器被触发时更频繁地发送数据的安全系统)。
-
时间加权平均值是处理不规则采样数据时获得无偏平均值的一种方法。为了说明Hyperfunctions的值以查找时间加权平均值,请考虑以下简单表对冷冻室温度进行建模的示例:
CREATE TABLE freezer_temps (
freezer_id int,
ts timestamptz,
temperature float);
以及一些不规则采样的时间序列数据,表示冰箱温度:
INSERT INTO freezer_temps VALUES
( 1, '2020-01-01 00:00:00+00', 4.0),
( 1, '2020-01-01 00:05:00+00', 5.5),
( 1, '2020-01-01 00:10:00+00', 3.0),
( 1, '2020-01-01 00:15:00+00', 4.0),
( 1, '2020-01-01 00:20:00+00', 3.5),
( 1, '2020-01-01 00:25:00+00', 8.0),
( 1, '2020-01-01 00:30:00+00', 9.0),
( 1, '2020-01-01 00:31:00+00', 10.5), -- door opened!
( 1, '2020-01-01 00:31:30+00', 11.0),
( 1, '2020-01-01 00:32:00+00', 15.0),
( 1, '2020-01-01 00:32:30+00', 20.0), -- door closed
( 1, '2020-01-01 00:33:00+00', 18.5),
( 1, '2020-01-01 00:33:30+00', 17.0),
( 1, '2020-01-01 00:34:00+00', 15.5),
( 1, '2020-01-01 00:34:30+00', 14.0),
( 1, '2020-01-01 00:35:00+00', 12.5),
( 1, '2020-01-01 00:35:30+00', 11.0),
( 1, '2020-01-01 00:36:00+00', 10.0), -- temperature stabilized
( 1, '2020-01-01 00:40:00+00', 7.0),
( 1, '2020-01-01 00:45:00+00', 5.0);
使用常规 SQL 函数计算冰箱的时间加权平均温度如下所示:
使用常规 SQL 的时间加权平均值
WITH setup AS (
SELECT lag(temperature) OVER (PARTITION BY freezer_id ORDER BY ts) as prev_temp,
extract('epoch' FROM ts) as ts_e,
extract('epoch' FROM lag(ts) OVER (PARTITION BY freezer_id ORDER BY ts)) as prev_ts_e,
*
FROM freezer_temps),
nextstep AS (
SELECT CASE WHEN prev_temp is NULL THEN NULL
ELSE (prev_temp + temperature) / 2 * (ts_e - prev_ts_e) END as weighted_sum,
*
FROM setup)
SELECT freezer_id,
avg(temperature), -- the regular average
sum(weighted_sum) / (max(ts_e) - min(ts_e)) as time_weighted_average
但是,使用TimescaleDB Hyperfunctions,我们将这种可能繁琐的编写和令人困惑的读取查询减少到更简单的五行查询:time_weight()
SELECT freezer_id,
avg(temperature),
average(time_weight('Linear', ts, temperature)) as time_weighted_average
FROM freezer_temps
GROUP BY freezer_id;
freezer_id | avg | time_weighted_average
------------+-------+-----------------------
1 | 10.2 | 6.636111111111111
5、使用Percentile Approximation做数据汇总
许多开发人员选择比百分位数更频繁地使用平均值和其他汇总统计数据,因为它们在计算资源和时间方面对大型时间序列数据集进行计算要“cheaper” 。
当我们设计Hyperfunctions时,我们考虑了如何捕获百分位数的好处(例如,对异常值的鲁棒性,与现实世界影响的更好对应),同时避免计算精确百分位数的一些陷阱。
TimescaleDB的百分位数近似Hyperfunctions使您能够有效地理解数据分布(例如,10%,平均值或50%,90%等),而无需对庞大的时间序列数据集执行昂贵的计算。
对于相对较大的数据集,您通常可以接受一些准确性权衡,以避免遇到高内存占用和网络成本的问题,同时能够更有效地并行计算百分位数并用于流数据。(在这篇文章中,您可以了解有关TimescaleDB的百分位数近似Hyperfunctions设计中所做的设计决策和权衡的更多信息。
TimescaleDB具有整个百分位数近似Hyperfunctions家族。调用它们的最简单方法是将percentile_agg聚合与approx_percentile访问器一起使用。例如,以下是我们计算特定 API 响应时间的 10%、 50% (平均值)和 90%的方法:
SELECT
approx_percentile(0.1, percentile_agg(response_time)) as p10,
approx_percentile(0.5, percentile_agg(response_time)) as p50,
approx_percentile(0.9, percentile_agg(response_time)) as p90
FROM responses;
百分位数近似的Hyperfunctions也可以用于TimescaleDB的连续聚合,这使得对非常大的数据集的聚合查询运行得更快。连续聚合以增量方式在后台连续和增量存储聚合查询的结果。因此,在运行查询时,只需要计算更改的数据,而不需要计算整个数据集。
与精确的百分位数相比,这是一个巨大的优势,因为您现在可以做一些事情,例如基线和警报更长的时间,而无需每次都从头开始重新计算!
例如,下面介绍如何使用连续聚合来识别最近的异常值并调查潜在问题。首先,我们从超表创建一个小时的聚合:responses
CREATE TABLE responses(
ts timestamptz,
response_time DOUBLE PRECISION);
SELECT create_hypertable('responses', 'ts');
CREATE MATERIALIZED VIEW responses_1h_agg
WITH (timescaledb.continuous)
AS SELECT
time_bucket('1 hour'::interval, ts) as bucket,
percentile_agg(response_time)
FROM responses
GROUP BY time_bucket('1 hour'::interval, ts);
要查找异常值,我们可以找到过去 30 秒内大于第 99 个百分位的数据:
SELECT * FROM responses
WHERE ts >= now()-'30s'::interval
AND response_time > (
SELECT approx_percentile(0.99, percentile_agg)
FROM responses_1h_agg
WHERE bucket = time_bucket('1 hour'::interval, now()-'1 hour'::interval)
);
要了解有关使用百分位数近似Hyperfunctions的更多信息,请阅读文档,尝试使用真实世界NFL数据的教程,并查看我们的解释器博客文章,了解为什么百分位数近似比平均值更有用。
6、first( ) 和 last( )
另一个常见问题是查找多个时间序列的第一个或最后一个值。这通常发生在 IoT 方案中,您希望监视不同位置的设备,但每个设备在不同的时间发回数据(因为设备可能会脱机、遇到连接问题、批量传输数据或只是具有不同的采样率)。
Hyperfunctions 允许您获取一列的值,按另一列排序。例如,返回基于聚合组中时间的最新温度值。lastlast(temperature, time)
这样,您可以更轻松地编写查询,例如,在多个位置查找上次记录的温度,因为每个位置可能具有不同的采样和记录数据速率:
SELECT location, last(temperature, time)
FROM conditions
GROUP BY location;
同样,Hyperfunctions还允许您获取一列的值,按另一列排序。 返回基于聚合组中时间的最早温度值:firstfirst(temperature, time)
SELECT device_id, first(temp, time)
FROM metrics
GROUP BY device_id;
first()并且还可用于更复杂的查询,例如查找特定时间间隔内的最新值。在下面的示例中,我们找到了过去一天中每台设备在五分钟内记录的最后一次温度:last()
SELECT device_id, time_bucket('5 minutes', time) AS interval,
last(temp, time)
FROM metrics
WHERE time > now () - INTERVAL '1 day'
GROUP BY device_id, interval
ORDER BY interval DESC;
在 TimescaleDB 2.7 中,我们进行了改进,以高达两倍的速度对和Hyperfunctions进行查询,并使内存使用率接近恒定。first() last()
🚀
注意:最后一个和第一个命令不使用索引,而是对其组执行顺序扫描。它们主要用于 GROUP BY 聚合中的有序选择,而不是作为 ORDER BY TIME DESC LIMIT 1 子句的替代方法,以查找最新值(使用索引)。
要了解更多信息,请参阅 first( 和 .)last()
7、使用COUNT DISTINCT查询,发挥内存效率
计算具有高基数的大型数据集中非重复值的确切数量需要大量的计算资源,这可能会影响数据库并发用户的查询性能和体验。
为了解决这个问题,TimescaleDB提供了Hyperfunctions来计算近似的计数DISTINCT。近似计数非重复数据不计算数据集的确切基数,而是估计唯一值的数量,以缩短计算时间。我们使用HyperLogLog,这是一个概率基数估计器,使用的内存明显少于等效查询。COUNT DISTINCT
Hyperloglog()是查询的近似对象。访问器函数从HyperLogLog对象获取不同值的数量,如下面的示例所示,它有效地估计了假设的NFT市场中唯一NFT和集合的数量:COUNT DISTINCT distinct_count()
SELECT
distinct_count(hyperloglog(32768, asset_id)) AS nft_count,
distinct_count(hyperloglog(32768, collection_id)) AS collection_count
FROM nft_sales
WHERE payment_symbol = 'ETH' AND time > NOW()-INTERVAL '3 months'
您还可以使用该函数来估计与直接运行相比,HyperLogLogLog 的相对标准误差。要了解有关近似Hyperfunctions的更多信息,请阅读文档。std_error()COUNT DISTINCT
8、通过使用Function Pipelines增强查询可读性和维护
🚀
注意:In the spirit of moving fast and not breaking things,本节中的Hyperfunctions作为实验性功能发布 - 请玩转它们,但不要在生产中使用它们。
在Timescale,我们是SQL的忠实粉丝。但是,正如我们在上面的许多示例中看到的那样,对于某些类型的分析和时间序列查询,SQL 可能会变得非常笨拙。输入 TimescaleDB 函数管道。
- TimescaleDB Function Pipelines 通过应用函数式编程和Python的Pandas和PromQL等流行工具的原则,从根本上改善了在PostgreSQL和SQL中分析数据的开发人员人体工程学。简而言之,它们提高了您的编码效率,使您的SQL代码更易于其他人理解和维护。
受函数式编程语言的启发,函数流水线使您能够通过组合多个函数来分析数据,从而在PostgreSQL中以更简单,更清晰的方式表达复杂逻辑。
最棒的是:我们以完全符合PostgreSQL的方式构建了函数管道!我们没有更改任何SQL语法,这意味着任何使用PostgreSQL的工具都能够使用函数管道支持数据分析。
要了解 TimescaleDB 函数管道的强大功能,请考虑以下 PostgreSQL 查询。
常规 PostgreSQL 查询:
SELECT device_id,
sum(abs_delta) as volatility
FROM (
SELECT device_id,
abs(val - lag(val) OVER (PARTITION BY device_id ORDER BY ts))
as abs_delta
FROM measurements
WHERE ts >= now() - '1 day'::interval) calc_delta
GROUP BY device_id;
使用 TimescaleDB 函数管道的查询可读性更强:
SELECT device_id,
timevector(ts, val) -> sort() -> delta() -> abs() -> sum()
as volatility
FROM measurements
WHERE ts >= now() - '1 day'::interval
GROUP BY device_id;
现在,此查询正在执行以下任务集,从而更加清楚了:
-
从测量表中获取最后一天的数据,分组如下:device_id
-
按时间列对数据进行排序
-
计算值之间的增量(或变化)
-
取增量的绝对值
-
然后取前面步骤的结果的总和
要了解有关使用TimescaleDB函数管道的更多信息,请阅读文档并查看我们的解释器博客文章:函数管道:使用自定义运算符将函数式编程构建到PostgreSQL中。
9、通过频率聚合简化频率分析
🚀
注意:In the spirit of moving fast and not breaking things, 本节中的Hyperfunctions作为实验性功能发布
请玩转它们,但不要在生产中使用它们。
使用大型数据集时,频率分析通常计算成本高昂,因为它需要对整个数据集进行计算才能获得准确的结果。您可能更愿意估计集合中最常见元素的频率,而不是计算数据集的所有元素。
频率聚合功能过大,或者使您能够以最小频率跟踪所有值列内的近似频率。freq_agg()
本示例通过 HomeSales 表中的字段(表示邮政编码)创建频率聚合。此聚合跟踪至少 5% 行中出现的任何值,使您能够有效地跟踪常见邮政编码:ZIPZIP
CREATE toolkit_experimental.freq_agg(0.05, ZIP) FROM HomeSales;
还可以使用频率聚合Hyperfunctions来估计数据集中特定值的最大和最小频率。例如,我们可以使用频率聚合Hyperfunctions找到整数 1-100 的最常见四舍五入平方根,如下所示:
SELECT value, min_freq, max_freq
FROM toolkit_experimental.into_values(
(SELECT toolkit_experimental.freq_agg(0.15, ceiling(sqrt(v))::int)
FROM generate_series(1,100) v),
0::int
);
value | min_freq | max_freq
-------+----------+----------
10 | 0.19 | 0.24
9 | 0.17 | 0.2
8 | 0.15 | 0.16
7 | 0.13 | 0.13
6 | 0.11 | 0.11
5 | 0.09 | 0.09
4 | 0.07 | 0.07
有趣的事实:由Metwally,Agrawal和El Abbadi在他们的论文《数据流中的频繁和Top-k元素的高效计算》中使用节省空间的算法在引擎下实现。Freq_agg
此外,我们经常想知道数据集的前N个值。为此,我们可以使用topn_agg函数,它估计列中存在的最大值。
下面是一个示例,用于从范围 (1,1000) 中的 100,000 个随机数中查找前五个最常见的平方根:topn_agg
SELECT toolkit_experimental.topn(
toolkit_experimental.topn_agg(5, ceiling(sqrt(random() * 1000))::int), 0::int)
FROM generate_series(1,100000);
topn
------
31
30
29
28
27
要了解有关使用TimescaleDB Hyperfunctions进行频率分析的更多信息,请阅读文档并在Timescale论坛中查看此解释器,其中涵盖了频率聚合,TopN聚合,状态聚合和仪表聚合。
10、立即通过Hyperfunctions提高您的工作效率
立即开始: TimescaleDB Hyperfunctions已预先加载,并可在 Timescale Cloud 中的每个托管和托管数据库服务上使用,这是开始使用 TimescaleDB 的最简单方法。
开始使用免费的 Timescale 云试用版 - 无需信用卡。或者使用TimescaleDB自我管理免费下载。
如果您想直接在现实世界的数据集上使用TimescaleDB Hyperfunctions,请开始我们的教程,该教程使用Hyperfunctions来揭示有关NFL(美式橄榄球)球员和球队的见解。
了解更多信息: 如果您想了解有关 TimescaleDB Hyperfunctions以及如何将其用于您的使用案例的更多信息,请阅读我们的操作指南和Hyperfunctions文档。
找不到您需要的功能? 在我们的 GitHub 项目上提出问题,或在 Slack 上或通过 Timescale 社区论坛与我们联系。我们喜欢与用户合作来简化SQL!
向我们发送您对实验性功能的反馈:to reinforce our commitment to moving fast and not breaking thing,我们将发布功能管道作为实验性功能 - 我们很乐意听取您的意见!您可以在 GitHub 上提出问题或加入讨论线程(如果您喜欢所看到的内容,GitHub ⭐ 始终受到欢迎和赞赏!
原文标题:How to Write Better Queries for Time-Series Data Analysis With Custom SQL Functions
原文作者:JF Joly Avthar Sewrathan Jerry Wu
原文地址:https://www.timescale.com/blog/how-to-write-better-queries-for-time-series-data-analysis-using-custom-sql-functions/





