AggregateBy 函数

AggregateBy 函数使用通过提供日历指定的新时间间隔聚集时间系列中的值。

此函数可以用于将较小时间间隔的时间系列转换为较大时间间隔的时间系列:例如,从每天时间系列生成每周时间系列。

如果提供可选的 startend DATETIME 参数,那么只有时间系列的这一部分聚集到新的时间间隔。

语法

AggregateBy(agg_express   lvarchar, 
           cal_name       lvarchar, 
           ts            TimeSeries
           flags         integer default 0
           start datetime year to fraction(5) default NULL,
           end datetime year to fraction(5) default NULL
)
returns TimeSeries;
agg_express
以逗号分隔的这些 SQL 聚集运算符的列表:MIN、MAX、MEDIAN、SUM、AVG、FIRST、LAST 或 Nth。
cal_name
定义聚集时间段的日历的名称。
ts
要聚集的时间系列。
flags(可选)
确定在聚集期间如何处理日历休息时间段中的数据点。请参阅 flags 自变量值
start(可选)
开始聚集的日期和时间。
end(可选)
结束聚集的日期和时间。

描述

AggregateBy 函数使用 cal_name 参数指定的日历将输入时间系列转换为规则的时间系列。agg_express 表达式对指定为 $colname$colnumber 的输入时间系列的列执行运算:例如,$high$1。生成的时间系列包含时间戳记列,再加上针对列表中每个表达式的一个列。

如果 MIN、MAX、MEDIAN、SUM 或 AVG 表达式用于非数字列,那么将出现错误。

使用以下语法,Nth 表达式将返回指定聚集时间段的列的值:
Nth($col, n)
$col
TimeSeries 行中列的名称或编号。
n
指示聚集时间段中 TimeSeries 行位置的正数或负数。正值 n 从聚集时间段中的第一行开始;因此,Nth($col, 1) 与 FIRST($col) 等效。负值 n 从聚集时间段中的最后一行开始;因此,Nth($col, -1) 与 LAST($col) 等效。

如果聚集时间段的第 n 行没有值,那么 Nth 函数将针对该时间段返回空值。使用 n 参数的正值执行 Nth 函数比使用负值效率更高。

聚集时间段由时间段的开始日期和时间表示。

聚集的输出时间系列的原点是输入时间系列的原点或之前的第一个时间段。每个输出时间段是从输出时间段的开始一直到(但不包括)下一个输出时间段的开始的所有输入时间段的聚集。

例如,假设想要将 2011 年 1 月 4 日(星期二)开始的每天时间系列聚集到每周时间系列。名为“days,”的输入日历在上午 12:00 点开始,名为“weeks,”的输出日历在星期一的上午 12:00 开始。

第一个输出时间是 2011 年 1 月 3 日 00:00;它是从输入原点 2011 年 1 月 4 日到 2011 年 1 月 9 日 23:59:59.99999 的所有输入值的聚集。第二个输出时间是 2011 年 1 月 10 日 00:00;它是从 2011 年 1 月 10 日到 2011 年 1 月 16 日 23:59:59.99999 的所有输入值的聚集。

正常情况下,AggregateBy 用于从细颗粒度规则时间系列向粗颗粒度时间系列聚集。但是,它也支持以下场景:
  • 从规则的时间系列转换到具有相同详细程度日历的时间系列。在这种情况下,AggregateBy 将时间向前推移以适应日历开始时间中的差异:例如,从 8:00 到 00:00。可以除去元素或添加空元素以适应启用/禁用模式中的差异。
  • 从规则的时间系列转换到具有更高详细程度日历的时间系列。在这种情况下,AggregateBy 对值进行复制。
  • 输入时间系列是不规则的。因为不规则时间系列的详细程度不是由日历的详细程度来决定,所以将这种情况视为从细颗粒度时间系列向粗颗粒度时间系列聚集。这种类型的聚集始终生成规则的时间系列。

flags 自变量值

flags 参数确定在聚集期间如何处理日历休息时间段中的数据点,以及如何管理隐藏的元素。该参数可以具有以下值。

0
(缺省值)休息时间段中的数据聚集到下一个输出时间段。
1
休息时间段中的数据聚集到前一个输出时间段。
2
指示扫描应该使用 TS_SCAN_HIDDEN 标志集运行(返回隐藏的元素)。
4
指示扫描应该使用 TS_SCAN_SKIP_HIDDEN 标志集运行(不返回隐藏的元素)。

例如,考虑输入时间系列具有没有休息日的每天日历:它具有从平日到周末的数据。如果使用工作日日历(5 天工作,2 天休息,从星期一开始)聚集此数据,那么 flags 参数 0 导致周末数据聚集到下个星期一的数据,flags 参数 1 导致周末数据聚集到上个星期五的数据。

另举一例,考虑如下定义的每季度日历:
'startdate(2010-1-1 00:00:00.00000), pattstart(2010-1-1 00:00:00.00000),
pattern({1 on, 2 off}, month' 

如果使用 flags 参数 0 或不使用 flags 参数聚集此日历,那么截止到(但不包括)2010-2-1 00:00:00.00000 的所有输入点都聚集到第一个输出元素中。从 2010-2-1 00:00:00.00000 到(但不包括)2010-5-1 00:00:00.00000 的所有点都聚集到第二个输出元素,依此类推。

如果 flags 参数为 1,那么截止到(但不包括)2010- 4-1 00:00:00.00000 的所有输入点都聚集到第一个输出元素中。从 2010-4-1 00:00:00.00000 到(但不包括)2010-7-1 00:00:00.00000 的所有点都聚集到第二个输出元素中,依此类推。AggregateBy 子句可能如下所示:
AggregateBy('max($high)', 'quarterlycal', ts, 1);

返回结果

如果是聚集到新的时间间隔,那么将返回聚集的时间系列,并且该时间系列始终是规则的。

示例

以下查询将 daily_stocks 时间系列聚集到每周时间系列。
insert into daily_stocks( stock_id, stock_name, stock_data)
   select stock_id, stock_name,
   AggregateBy( 'max($high), min($low),last($final),sum($vol)',
   'weekcal', stock_data)::TimeSeries(stock_bar)
   from daily_stocks;
以下查询子句从每周中选择第二个价格:
AggregateBy( 'Nth($price, 2)', 'weekly', ts)
此查询子句从每周中选择第二个到最后一个价格:
AggregateBy( 'Nth($price, -2)', 'weekly', ts)