カテゴリ:

クエリ構文

AT | BEFORE

AT または BEFORE 句は、Snowflake Time Travelに使用されます。クエリでは、テーブル名の直後の FROM 句で指定され、オブジェクトの履歴データが要求される過去のポイントを決定します。

  • AT キーワードは、指定されたパラメーターに等しいタイムスタンプを持つステートメント、またはトランザクションによる変更がリクエストに含まれることを指定します。

  • BEFORE キーワードは、要求が指定されたパラメーターの直前のポイントを参照することを指定します。

詳細については、 Time Travelの理解と使用 をご参照ください。

こちらもご参照ください:

FROM

構文

SELECT ...
FROM ...
  {
   AT( { TIMESTAMP => <timestamp> | OFFSET => <time_difference> | STATEMENT => <id> | STREAM => '<name>' } ) |
   BEFORE( STATEMENT => <id> )
  }
[ ... ]
Copy
TIMESTAMP => timestamp

Time Travelに使用する正確な日付と時刻を指定します。値は明示的に TIMESTAMP にキャストする必要があります。

OFFSET => time_difference

Time Travelに使用する現在の時刻との差を秒単位で -N の形式で指定します。 N は整数または数式です(例: -120 は120秒、 -30*60 は1800秒または30分)。

STATEMENT => id

Time Travelの参照ポイントとして使用するステートメントのクエリ ID を指定します。このパラメーターは、次のいずれかのタイプのステートメントをサポートします。

  • DML (例: INSERT、 UPDATE、 DELETE)

  • TCL (BEGIN、 COMMIT トランザクション)

  • SELECT

クエリ ID は、過去14日以内に実行されたクエリを参照する必要があります。クエリ ID が14日以上経過したクエリを参照している場合は、次のエラーが返されます。

Error: statement <query_id> not found

この制限を回避するには、参照されるクエリのタイムスタンプを使用します。

STREAM => 'name'

クエリされたテーブルまたはビューの既存のストリームに対する識別子(つまり、名前)を指定します。ストリーム内の現在のオフセットは、ソースオブジェクトの変更データを返すための AT 時点として使用されます。

このキーワードは、ストリームを作成(CREATE STREAM を使用)または変更データをクエリ( CHANGES 句を使用)するの場合にのみサポートされます。例については、次のトピックを参照してください。

使用上の注意

  • Snowflakeのデータは、システム時間の正確な値とわずかに異なる可能性があるタイムスタンプによって識別されます。

  • TIMESTAMP または OFFSET の値は定数式でなければなりません。

  • TIMESTAMP の最小時間解像度はミリ秒です。

  • 要求されたデータがTime Travel保持期間(デフォルトは1日)を超えている場合、ステートメントは失敗します。

    さらに、要求されたデータがTime Travel保持期間内であっても、履歴データが利用できない場合(保持期間が延長された場合など)、ステートメントは失敗します。

  • 指定されたTime Travel時間がオブジェクトが作成された時点またはそれ以前の場合、ステートメントは失敗します。

  • 履歴テーブルデータにアクセスすると、その結果にはテーブルの現在の定義に基づく列やデフォルト値などが含まれます。マテリアライズドビュー以外についても同様です。たとえば、テーブルを変更して列を追加した場合に、列が追加された時点より前の履歴データをクエリすると、新しい列を含む結果が返されます。

  • 履歴データには、現在のデータと同じアクセス制御要件があります。変更は遡及的に適用されます。

トラブルシューティング

エラー

Time travel data is not available for table <tablename>

原因

場合によっては、これはタイムスタンプが期待される場所で文字列を使用することによって引き起こされます。

解決策

文字列をタイムスタンプにキャストします。

... AT(TIMESTAMP => '2018-07-27 12:00:00')               -- fails
... AT(TIMESTAMP => '2018-07-27 12:00:00'::TIMESTAMP)    -- succeeds
Copy

特定のタイムスタンプを使用して、テーブルから履歴データを選択します。

SELECT * FROM my_table AT(TIMESTAMP => 'Fri, 01 May 2015 16:20:00 -0700'::timestamp);
Copy
SELECT * FROM my_table AT(TIMESTAMP => TO_TIMESTAMP(1432669154242, 3));
Copy

5分前の時点でテーブルから履歴データを選択します。

SELECT * FROM my_table AT(OFFSET => -60*5) AS T WHERE T.flag = 'valid';
Copy

テーブルから履歴データを選択しますが、指定したトランザクションによる変更は含まれません。

SELECT * FROM my_table BEFORE(STATEMENT => '8e5d0ca9-005e-44e6-b858-a8f5b37c5726');
Copy

指定されたトランザクションから生じるテーブルデータの差を返します。

SELECT oldt.* ,newt.*
  FROM my_table BEFORE(STATEMENT => '8e5d0ca9-005e-44e6-b858-a8f5b37c5726') AS oldt
    FULL OUTER JOIN my_table AT(STATEMENT => '8e5d0ca9-005e-44e6-b858-a8f5b37c5726') AS newt
    ON oldt.id = newt.id
WHERE oldt.id IS NULL OR newt.id IS NULL;
Copy