TIME_SLICE

按照不同的固定时间间隔聚合数据,并将向上舍入的输入 TIMESTAMP 值返回到与时间片间隔开始或结束时间相对应的值。

提供输入 TIMESTAMP 值,例如 2000-10-28 00:00:01,3 秒时间片间隔的开始时间为 2000-10-28 00:00:00,同一时间片结束时间为 2000-10-28 00:00:03

行为类型

不可变

语法

TIME_SLICE( expression, slice-length [, 'time‑unit' [, 'start‑or‑end' ] ] )

参数

表达式
以下几项之一:
  • 列类型 TIMESTAMP

  • 可解析为 TIMESTAMP 值的字符串常量。例如:

    '2004/10/19 10:23:54'

Vertica 对每一行的表达式求值。

slice-length
指定片长度的正整数。
time‑unit
片的时间单位为以下之一:
  • HOUR

  • MINUTE

  • SECOND (默认值)

  • MILLISECOND

  • MICROSECOND

start‑or‑end
使用以下字符串之一指定返回值是否与开始或结束时间关联:
  • START (默认值)

  • END

null 实参处理

TIME_SLICE 按如下所示处理 null 实参:

  • TIME_SLICE 在任何一个 slice-lengthtime-unitstart-or-end 参数为 null 时返回错误。

  • 如果表达式为 null 且 slice-lengthtime‑unitstart‑or‑end 包含合法值,则 TIME_SLICE 返回 NULL 值而不是错误。

使用

以下命令返回(默认) 3 秒时间片的开始时间:

=> SELECT TIME_SLICE('2009-09-19 00:00:01', 3);
     TIME_SLICE
---------------------
 2009-09-19 00:00:00
(1 row)

以下命令返回 3 秒时间片的结束时间:

=> SELECT TIME_SLICE('2009-09-19 00:00:01', 3, 'SECOND', 'END');
     TIME_SLICE
---------------------
 2009-09-19 00:00:03
(1 row)

此命令返回使用 3 秒时间片的结果(毫秒):

=> SELECT TIME_SLICE('2009-09-19 00:00:01', 3, 'ms');
       TIME_SLICE
-------------------------
 2009-09-19 00:00:00.999

(1 row)

此命令返回使用 9 秒时间片的结果(毫秒):

=> SELECT TIME_SLICE('2009-09-19 00:00:01', 3, 'us');
         TIME_SLICE
----------------------------
 2009-09-19 00:00:00.999999
(1 row)

下一个示例使用 3 秒间隔,输入值为 '00:00:01'。为了特别突出秒数,该示例忽略日期,但所有值均隐含为时间戳的一部分,规定输入为 '00:00:01'

  • '00:00:00 ' 是 3 秒时间片的开始时间

  • '00:00:03 ' 是 3 秒时间片的结束时间。

  • '00:00:03' 也是 3 秒时间片的 second 开始时间。在时间片界限中,时间片的结束值不属于该时间片,它是下一个时间片的开始值。

时间片间隔不是 60 秒的因数,例如以下示例中,规定片长度为 9,该时间片不会始终以 00 秒数开始或结束:

=> SELECT TIME_SLICE('2009-02-14 20:13:01', 9);
     TIME_SLICE
---------------------
 2009-02-14 20:12:54
(1 row)

这是预期行为,因为所有时间片的以下属性为真:

  • 长度相同

  • 连续(时间片之间没有间隙)

  • 无重叠

为强制上述示例 ('2009-02-14 20:13:01') 的开始时间为 '2009-02-14 20:13:00',请调整输出时间戳值,使剩余 54 计数至 60:

=> SELECT TIME_SLICE('2009-02-14 20:13:01', 9 )+'6 seconds'::INTERVAL AS time;
        time
---------------------
 2009-02-14 20:13:00
(1 row)

或者,您可以使用能被 60 整除的不同片长度,例如 5:

=> SELECT TIME_SLICE('2009-02-14 20:13:01', 5);
     TIME_SLICE
---------------------
 2009-02-14 20:13:00
(1 row)

TIMESTAMPTZ 值隐式强制转换为 TIMESTAMP。例如,以下两个语句的效果相同。

=> SELECT TIME_SLICE('2009-09-23 11:12:01'::timestamptz, 3);
     TIME_SLICE
---------------------
 2009-09-23 11:12:00
(1 row)


=> SELECT TIME_SLICE('2009-09-23 11:12:01'::timestamptz::timestamp, 3);

     TIME_SLICE
---------------------
 2009-09-23 11:12:00
(1 row)

示例

您可以使用 SQL 分析函数 FIRST_VALUELAST_VALUE 来找到每个时间片组(属于相同时间片的行集合)内的第一个/最后一个价格。如果您要通过从每个时间片组选择一行来取样输入数据,此结构很实用。

=> SELECT date_key, transaction_time, sales_dollar_amount,TIME_SLICE(DATE '2000-01-01' + date_key + transaction_time, 3),
FIRST_VALUE(sales_dollar_amount)
OVER (PARTITION BY TIME_SLICE(DATE '2000-01-01' + date_key + transaction_time, 3)
     ORDER BY DATE '2000-01-01' + date_key + transaction_time) AS first_value
FROM store.store_sales_fact
LIMIT 20;

 date_key | transaction_time | sales_dollar_amount |     time_slice      | first_value
----------+------------------+---------------------+---------------------+-------------
        1 | 00:41:16         |                 164 | 2000-01-02 00:41:15 |         164
        1 | 00:41:33         |                 310 | 2000-01-02 00:41:33 |         310
        1 | 15:32:51         |                 271 | 2000-01-02 15:32:51 |         271
        1 | 15:33:15         |                 419 | 2000-01-02 15:33:15 |         419
        1 | 15:33:44         |                 193 | 2000-01-02 15:33:42 |         193
        1 | 16:36:29         |                 466 | 2000-01-02 16:36:27 |         466
        1 | 16:36:44         |                 250 | 2000-01-02 16:36:42 |         250
        2 | 03:11:28         |                  39 | 2000-01-03 03:11:27 |          39
        3 | 03:55:15         |                 375 | 2000-01-04 03:55:15 |         375
        3 | 11:58:05         |                 369 | 2000-01-04 11:58:03 |         369
        3 | 11:58:24         |                 174 | 2000-01-04 11:58:24 |         174
        3 | 11:58:52         |                 449 | 2000-01-04 11:58:51 |         449
        3 | 19:01:21         |                 201 | 2000-01-04 19:01:21 |         201
        3 | 22:15:05         |                 156 | 2000-01-04 22:15:03 |         156
        4 | 13:36:57         |                -125 | 2000-01-05 13:36:57 |        -125
        4 | 13:37:24         |                -251 | 2000-01-05 13:37:24 |        -251
        4 | 13:37:54         |                 353 | 2000-01-05 13:37:54 |         353
        4 | 13:38:04         |                 426 | 2000-01-05 13:38:03 |         426
        4 | 13:38:31         |                 209 | 2000-01-05 13:38:30 |         209
        5 | 10:21:24         |                 488 | 2000-01-06 10:21:24 |         488
(20 rows)

TIME_SLICE 将事务处理时间四舍五入至 3 秒片长度。

以下示例使用分析(窗口) OVER 子句来返回每个 3 秒时间片分区中的最后交易价格(按 TickTime 排序的最后一行):

=> SELECT DISTINCT TIME_SLICE(TickTime, 3), LAST_VALUE(price)OVER (PARTITION BY TIME_SLICE(TickTime, 3)
ORDER BY TickTime ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING);

在下一个示例中,会对每个输入记录求一次 FIRST_VALUE 的值,而且按升序值对数据进行排序。使用 SELECT DISTINCT 移除重复值,每个 TIME_SLICE 仅返回一个输出记录:

=> SELECT DISTINCT TIME_SLICE(TickTime, 3), FIRST_VALUE(price)OVER (PARTITION BY TIME_SLICE(TickTime, 3)
ORDER BY TickTime ASC)
FROM tick_store;
     TIME_SLICE      | ?column?
---------------------+----------
 2009-09-21 00:00:06 |    20.00
 2009-09-21 00:00:09 |    30.00
 2009-09-21 00:00:00 |    10.00
(3 rows)

上述查询的信息输出也可以返回每个时间片内的 MINMAXAVG 交易价格。

=> SELECT DISTINCT TIME_SLICE(TickTime, 3),FIRST_VALUE(Price) OVER (PARTITION BY TIME_SLICE(TickTime, 3)
ORDER BY TickTime ASC),
  MIN(price) OVER (PARTITION BY TIME_SLICE(TickTime, 3)),
  MAX(price) OVER (PARTITION BY TIME_SLICE(TickTime, 3)),
  AVG(price) OVER (PARTITION BY TIME_SLICE(TickTime, 3))
FROM tick_store;

另请参阅