时间旅行查询语法和时间戳记
查询语法
具有一个或多个临时子句的 SELECT 查询是时间旅行查询。 时间旅行查询可能在 INSERT,UPDATE,DELETE,MERGE 或 CREATE TABLE AS SELECT (CTAS) 语句中显示为 sub-SELECTs。
此外,时间旅行查询可能出现在视图定义 (CREATE VIEW,带或不带 OR REPLACE) 或存储过程定义 (CREATE PROCEDURE,带或不带 OR REPLACE) 中。 在任一情况下,语法中的时间戳记表达式 (例如,CURRENT_TIMESTAMP - INTERVAL ‘1 day’
) 都不会在视图或过程定义时求值,而是在用户或应用程序查询视图或调用过程时求值。
SELECT 或 sub-SELECT 中的任何基本表引用 (表名,具有或不具有数据库和模式名,以及具有或不具有别名) 都可能具有可选的临时子句,该子句由后跟下列其中一个值的关键字 FOR SYSTEM_TIME 组成:
AS OF <TIMESTAMP EXPRESSION>
BEFORE <TIMESTAMP EXPRESSION>
BETWEEN <TIMESTAMP EXPRESSION 1> AND <TIMESTAMP EXPRESSION 2>
FROM <TIMESTAMP EXPRESSION 1> TO <TIMESTAMP EXPRESSION 2>
每个 TIMESTAMP EXPRESSION
必须是下列其中一项:
- 文字时间戳记值。 例如,
‘2022-10-31 20:00:00’
。 - 值为时间戳记的查询参数或主变量。
- 返回或隐式转换为时间戳记的内置函数。 例如,
CURRENT_DATE
,CURRENT_TIMESTAMP
或 (等效)NOW()
或CURRENT_TIMESTAMP(subsecond-digits)
或 (等效)NOW(subsecond-digits)
。 - 对表中的所有行求值为单个时间戳记的表达式。 例如,
CURRENT_TIMESTAMP - INTERVAL ‘1 day’
。 表达式不能引用表列或非确定性函数 (例如,RANDOM()
) 或 sub-SELECT。 - 特殊标识 RETENTION_START_TIMESTAMP,在 AS OF,BETWEEN 和 FROM (但不是 BEFORE,AND 或 TO) 的特定情况下。 这是指保留时间开始时间戳记,这是可用于时间旅行查询的最早可能的行插入时间戳记或删除时间戳记。 有关保留时间开始时间戳记,插入时间戳记和删除时间戳记的更多信息,请参阅 时间旅行查询中的时间戳记。
起始时间
当您想要检索过去任何特定时间的数据状态时,可以使用 AS OF 子句。
语法 | 描述 |
---|---|
AS OF <TIMESTAMP EXPRESSION 1> | 包含在 TIMESTAMP EXPRESSION 1 求值为的时间戳记有效的所有行,这些行的插入时间戳记小于或等于 TIMESTAMP EXPRESSION 1,并且其删除时间戳记为 NULL 或大于 TIMESTAMP EXPRESSION 1。 如果 TIMESTAMP EXPRESSION 1 小于表的保留时间开始时间戳记,那么将返回错误。 |
之前
当您想要检索数据的状态时,可以使用 BEFORE 子句,就像在过去的任何特定时间之前一样。
语法 | 描述 |
---|---|
先于<TIMESTAMP EXPRESSION 1> | 包括在 TIMESTAMP EXPRESSION 1 求值为的时间戳记之前有效的所有行。 其插入时间戳记严格小于 TIMESTAMP EXPRESSION $TAG1 且其删除时间戳记为 NULL 或大于 TIMESTAMP EXPRESSION 1。 如果 TIMESTAMP EXPRESSION 1 小于或等于表的保留时间开始时间戳记,那么将返回错误。 |
从 ...TO 和 BETWEEN...与
您可以使用 FROM...目标 和 BETWEEN...用于数据审计或趋势分析的 AND 子子句。 当您需要在一段时间内获取部分或全部行的所有历史转换时,请使用它。
语法 | 描述 |
---|---|
从 < 时间戳表达式 1> 到 < 时间戳表达式 2> | 包括从 TIMESTAMP EXPRESSION $TAG1 到 TIMESTAMP EXPRESSION 2 (互斥) 在任何时候都有效的所有行,这些行的插入时间戳记严格小于 TIMESTAMP EXPRESSION 2,并且其删除时间戳记为 NULL 或大于 TIMESTAMP EXPRESSION 1。 如果 TIMESTAMP EXPRESSION $TAG1 或 TIMESTAMP EXPRESSION 2 小于或等于表的保留时间开始时间戳记,那么将返回错误。 如果 TIMESTAMP EXPRESSION $TAG1 大于或等于 TIMESTAMP EXPRESSION 2,那么查询不会生成任何行。 |
介于 <TIMESTAMP EXPRESSION 1> 与 <TIMESTAMP EXPRESSION 2> 之间 | 包括 TIMESTAMP EXPRESSION $TAG1 与 TIMESTAMP EXPRESSION 2 (含) 之间任何时候都有效的所有行,这些行的插入时间戳记小于或等于 TIMESTAMP EXPRESSION 2,并且其删除时间戳记为 NULL 或大于 TIMESTAMP EXPRESSION 1。 如果 TIMESTAMP EXPRESSION $TAG1 或 TIMESTAMP EXPRESSION 2 小于表的保留时间开始时间戳记,那么将返回错误。 如果 TIMESTAMP EXPRESSION $TAG1 大于 TIMESTAMP EXPRESSION 2,那么查询不会生成任何行。 |
差旅时间查询中的时间戳记
保留时间间隔和保留时间段
表的保留时间间隔定义经过其删除时间戳记的天数,历史 (已删除) 行可用于时间旅行查询。 在任何给定时间,保留时间段以当前时间戳记 (日期和时间) 结束,并向后延长给定天数。 这是一个随着当前系统时间推进而前进的滑动时间窗口。
保留时间下限
在大多数情况下,表的保留时间下限是将表定义为时态表的日期和时间。 这可能是在运行 CREATE TABLE 命令时,或者在上次将表的 DATA_VERSION_RETENTION_TIME 从零更改为非零时。
保留时间开始时间戳记
在将表定义为临时表时 (当定义了保留时间下限时),在保留时间周期内没有可用的历史行。 为了捕获历史行的实际可用距离 (对时间旅行查询可见) 的概念,定义了表的保留时间开始时间戳记。 保留时间开始时间戳记是下列值中较大的值:
- 保留时间周期的开始 (当前日期/时间减去保留时间间隔)。
- 保留时间下限。
表的保留时间开始时间戳记在以下操作中生效:
-
时间旅行查询 (SELECT 和 sub-SELECT)
如果尝试对保留时间开始时间戳记之前删除的历史行运行查询,那么将返回错误。
如果要尽可能远地查询历史数据,可以在时间旅行查询中使用 RETENTION_START_TIMESTAMP 关键字。 如果执行此操作,那么可以避免尝试自行计算正确的时间戳记。 通过扩展,您可以消除在值变得太旧 (早于保留时间开始时间戳记) 时迂到错误的风险。
-
GROOM TABLE 时间旅行查询不再需要在保留时间开始时间戳记之前删除的历史行,可以回收这些行。
行时间戳记和有效性
当前行或历史行的插入时间戳记是事务插入已落实行的日期/时间。 不是运行插入行的特定 INSERT,UPDATE 或 MERGE 语句的时间。
如果在保留开始时间戳记之前落实的行的插入事务,那么该行将被视为已在保留开始时间戳记处插入。 这通常仅适用于将非时态表变更为时态表时的现有行。
事务尚未落实的插入行没有插入时间戳记。 对于时间旅行查询,此类行将永远不可见。
在时间旅行查询中,可以使用时态表的 _SYS_START 虚拟列来选择插入时间戳记。
历史行的删除时间戳记是事务删除已落实行的日期/时间。 不是运行删除该行的特定 DELETE,UPDATE,MERGE 或 TRUNCATE 语句的时间。
如果时态表被截断,那么现有表行可用于时间旅行查询,并且在落实截断事务时被视为已被删除。
如果在保留开始时间戳记之前落实了删除 (或截断) 事务,那么会将已删除的行视为已在保留开始时间戳记处删除。 这通常仅适用于将非时态表变更为时态表时的现有已删除行; 此类行对于针对该表的时间旅行查询不可见。
如果某个历史行的删除时间戳记在表的保留期内,那么该历史行可能对该表的临时查询可视。 如果此条件为 true,那么无法从表中除去历史行 (使用 GROOM TABLE)。
当前行 (未删除或标记为待删除但未落实) 的删除时间戳记为 NULL。
在时间旅行查询中,可以使用时态表的 _SYS_END 虚拟列来选择删除时间戳记。
从插入时间戳记到删除时间戳记之前,历史行被视为有效。 当前行从其插入时间戳记开始被视为有效。 时间旅行查询使用时间戳记或时间戳记表达式仅返回在某个时间点或某个时间段内的任何时间点有效的行 (当前行或历史行)。
最近插入和删除的行的插入和删除时间戳记可能无法用于时间旅行查询,直到在插入和删除事务落实之后的短时间内 (通常在 3 分钟内)。