查询历史数据

您可以使用命令行或 Web 控制台中的查询编辑器 来运行查询。

下表定义用于示例查询。

CREATE TABLE PRODUCT (PRODUCTID INTEGER, DESC VARCHAR (100), PRICE DECIMAL) DATA_VERSION_RETENTION_TIME 30;

将在不同时间插入以下行。 插入的落实时间 (插入时间戳记或 _SYS_START 值) 在 SQL 注释中指示。

INSERT INTO PRODUCT VALUES(1001, 'Jacket', 102.00); -- 2020-10-23 16:00:00
INSERT INTO PRODUCT VALUES(1002, 'Gloves',  20.50); -- 2020-10-23 16:05:00
INSERT INTO PRODUCT VALUES(1003, 'Hat',     18.99); -- 2020-10-23 16:10:00
INSERT INTO PRODUCT VALUES(1004, 'Shoes', 125.25);  -- 2020-10-23 16:15:00

显示具有插入和删除时间戳记的数据

SELECT 命令在发出查询时显示具有关联的插入和删除时间戳记值的表数据。 _SYS_START_SYS_END 时间戳记仅在时间旅行查询中可用,因此使用 AS OF NOW ()

SELECT *, _SYS_START, _SYS_END FROM <table_name> FOR SYSTEM_TIME AS OF NOW();

示例:

SELECT *, _SYS_START, _SYS_END FROM PRODUCT FOR SYSTEM_TIME AS OF NOW();
PRODUCTID | DESCRIPTION | PRICE   |     _SYS_START      | _SYS_END
----------+-------------+---------+---------------------+-----------
     1001 | Jacket      | 102.00  | 2020-10-23 16:00:00 |
     1002 | Gloves      |  20.50  | 2020-10-23 16:05:00 |
     1003 | Hat         |  18.99  | 2020-10-23 16:10:00 |
     1004 | Shoes       | 125.25  | 2020-10-23 16:15:00 |
(4 rows)

使用 AS OF 查询特定时间的数据

SELECT *, _SYS_START, _SYS_END FROM <table_name> FOR SYSTEM_TIME AS OF <TIMESTAMP EXPRESSION>;

示例:

SELECT *, _SYS_START, _SYS_END FROM PRODUCT FOR SYSTEM_TIME AS OF '2020-10-23 16:30:00';
PRODUCTID  | DESCRIPTION | PRICE  |     _SYS_START      |      _SYS_END
-----------+-------------+--------+---------------------+---------------------
      1001 | Jacket      | 102.00 | 2020-10-23 16:00:00 |
      1002 | Gloves      |  20.50 | 2020-10-23 16:05:00 |
      1003 | Hat         |  18.99 | 2020-10-23 16:10:00 |
      1004 | Shoes       | 125.25 | 2020-10-23 16:15:00 | 2020-10-23 17:00:00
(4 rows)

在此示例中,Shoes 的价格已在指定的 AS OF 时间戳记后修改。 系统返回先前的有效行。

另请参阅 AS OF 条款

使用 BEFORE 查询特定时间的数据

SELECT *, _SYS_START, _SYS_END FROM <table_name> FOR SYSTEM_TIME BEFORE <TIMESTAMP EXPRESSION>;

示例:

SELECT *, _SYS_START, _SYS_END FROM PRODUCT FOR SYSTEM_TIME BEFORE '2020-10-23 17:00:00';
PRODUCTID  | DESCRIPTION | PRICE  |     _SYS_START      |      _SYS_END
-----------+-------------+--------+---------------------+---------------------
      1001 | Jacket      | 102.00 | 2020-10-23 16:00:00 |
      1002 | Gloves      |  20.50 | 2020-10-23 16:05:00 |
      1003 | Hat         |  18.99 | 2020-10-23 16:10:00 |
      1004 | Shoes       | 125.25 | 2020-10-23 16:15:00 | 2020-10-23 17:00:00
(4 rows)

在此示例中,Shoes 的价格已在 BEFORE 时间戳记之后或之后修改。 系统返回先前的有效行。

另请参阅 BEFORE 子句

查询某个时间段内所有行的数据

使用 FROM...TO 第 2 款

SELECT *, _SYS_START, _SYS_END FROM <table_name> FOR SYSTEM_TIME FROM <TIMESTAMP EXPRESSION 1> TO<TIMESTAMP EXPRESSION 2>WHERE <condition>;

如果要尽可能远地查询历史数据,可以在时间旅行查询中使用 RETENTION_START_TIMESTAMP 关键字。 如果执行此操作,那么可以避免尝试自行计算正确的时间戳记。 通过扩展,如果值变得太旧 (早于保留时间开始时间戳记),那么可降低发生错误的风险。

示例:

SELECT *, _SYS_START, _SYS_END FROM PRODUCT FOR SYSTEM_TIME FROM RETENTION_START_TIMESTAMP TO '2020-10-23 17:10:00' WHERE PRODUCTID = 1004;
PRODUCTID  | DESCRIPTION | PRICE  |     _SYS_START      |      _SYS_END
-----------+-------------+--------+---------------------+---------------------
      1004 | Shoes       | 125.25 | 2020-10-23 16:15:00 | 2020-10-23 17:00:00
      1004 | Shoes       | 100.00 | 2020-10-23 17:00:00 |
(2 rows)

在此示例中,查询将搜索在指定时间段内对 PRODUCTID 1004 进行的所有更改 (不包括 TO 时间戳记)。

另请参阅 FROM...致 款。

使用 BETWEEN...AND 子句

SELECT *, _SYS_START, _SYS_END FROM <table_name> FOR SYSTEM_TIME BETWEEN <TIMESTAMP EXPRESSION 1> AND <TIMESTAMP EXPRESSION 2>;

示例:

SELECT *, _SYS_START, _SYS_END FROM PRODUCT FOR SYSTEM_TIME BETWEEN '2020-10-23 16:00:00' AND '2020-10-23 17:10:00';
PRODUCTID  | DESCRIPTION | PRICE  |     _SYS_START      |      _SYS_END
-----------+-------------+--------+---------------------+---------------------
      1001 | Jacket      | 102.00 | 2020-10-23 16:00:00 |
      1002 | Gloves      |  20.50 | 2020-10-23 16:05:00 |
      1003 | Hat         |  18.99 | 2020-10-23 16:10:00 |
      1004 | Shoes       | 125.25 | 2020-10-23 16:15:00 | 2020-10-23 17:00:00
      1004 | Shoes       | 100.00 | 2020-10-23 17:00:00 |
(5 rows)

在此示例中,查询将搜索在特定时间段内对产品表进行的所有更改,直到并包括 AND 时间戳记。

另请参阅 BETWEEN...AND 子句

正在恢复表

BEGIN;
ALTER TABLE <table_name> RENAME TO <new_table_name>;
CREATE TABLE <table_ name> AS
  SELECT * FROM <new_table_name> FOR SYSTEM_TIME <temporal_clause>;
DROP TABLE <new_table_name>; -- or, keep it for diagnostics
COMMIT;

示例:

BEGIN;
ALTER TABLE PRODUCT RENAME TO PRODUCT_BAK;
CREATE TABLE PRODUCT AS
  SELECT * FROM FLIGHT_BAK FOR SYSTEM_TIME AS OF '2022-11-01 11:30:00';
DROP TABLE FLIGHT_BAK; -- or, keep it for diagnostics
COMMIT;

在此示例中,您怀疑对 PRODUCT 表进行了不正确的批量更改,并且希望还原这些更改。

复原已更新的行

UPDATE <table> SET <col> = <expression> [, <col> = <expression>...]
  FROM (SELECT <col> [, <col> ...] FROM <fromlist> WHERE <condition> FOR SYSTEM_TIME <temporal_clause>) AS <alias>;

示例:

UPDATE PRODUCT SET PRICE=P.PRICE
  FROM (SELECT PRICE FROM PRODUCT WHERE PRODUCTID=1002FOR SYSTEM_TIME BEFORE ‘2022-11-01 09:22:41’) AS P;

在此示例中,产品的价格未正确更新,需要复原。

另请参阅 时间旅行查询语法和时间戳记

复原已删除的行

INSERT INTO <table>
  SELECT * FROM <table>
  WHERE <condition> FOR SYSTEM_TIME <temporal_clause>;

示例:

INSERT INTO PRODUCT
  SELECT * FROM PRODUCT
  WHERE PRODUCTID=1004FOR SYSTEM_TIME BEFORE ‘2022-11-01 12:45:07’;

在此示例中,未正确删除产品,需要将其复原。

时间旅行查询语法和时间戳记