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‑unit 实参时,才能包含此参数。 -
null 实参处理
TIME_SLICE
按如下所示处理 null 实参:
-
TIME_SLICE
在任何一个 slice-length、time-unit 或 start-or-end 参数为 null 时返回错误。 -
如果表达式为 null 且 slice-length、time‑unit 或 start‑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_VALUE
和
LAST_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);
注意
如果您从分析子句中省略窗口子句,则LAST_VALUE
默认为 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
。结果似乎并不直观,因为与当前分区底部返回值不一样,该函数返回 window 顶部,而且随着正处理的当前输入行持续变化。有关详细信息,请参阅时序分析和 SQL 分析。
在下一个示例中,会对每个输入记录求一次 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)
上述查询的信息输出也可以返回每个时间片内的 MIN
、MAX
和 AVG
交易价格。
=> 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;