SnowflakeでSQLを書いていて、「同じ日付なのに、なぜかa_date <= b_dateが期待と違う結果になる…」といった経験はありませんか?
それは、タイムゾーンの罠にハマっている可能性があります。
この記事では、Snowflakeにおけるタイムゾーン付きデータ(TIMESTAMP_TZ)とタイムゾーンなしデータ(TIMESTAMP_NTZ)の比較で発生する問題と、それをJST(日本標準時)ベースで簡易に解決するSQLを紹介します。
なぜ比較結果が狂うのか?
ご指摘のケースでは、以下のようなデータで比較が行われていました。
| 項目 | データ型(想定) | 値 |
|---|---|---|
a_date | TIMESTAMP_NTZ | '2025-12-09 00:00:00' |
b_date | TIMESTAMP_TZ | '2025-12-09 00:00:00 +09:00' |
a_date(タイムゾーンなし)とb_date(タイムゾーンあり)の「見た目の日付」は同じです。しかし、この状態で比較を実行すると、a_date <= b_dateがFALSE(つまり、a_dateの方が新しい)と判定されてしまう場合があります。
タイムゾーンによる自動変換
Snowflakeでは、異なるタイムスタンプ型が混在した比較が行われる際、b_date(タイムゾーン付き)の情報が優先され、内部的にUTCに変換されてから比較されることが原因です。
a_date(NTZ):2025-12-09 00:00:00(NTZ)b_date(TZ):2025-12-09 00:00:00 +09:00$\to$2025-12-08 15:00:00UTCに変換a_dateの擬似UTC変換:a_dateをセッションタイムゾーン(例: UTC)と見なすと、2025-12-09 00:00:00UTCのまま- 比較:
2025-12-09 00:00:00$\le$2025-12-08 15:00:00$\to$ FALSE(a_dateの方が新しいと判定!)
このように、データ型が揃っていないために、私たちが期待する「日本の時刻としての比較」が行われなくなってしまうのです。
JST(見た目の時刻)で簡易比較する解決策
最もシンプルで、日本のユーザーが入力・確認した時刻(JST)として比較したい場合に有効な方法は、b_dateからタイムゾーン情報だけを削除し、タイムゾーンなしの時刻 (TIMESTAMP_NTZ) に揃えることです。
これは、CASTや::を使ってデータ型を変換するだけで実現できます。
💡 解決コード
a_date <= b_date::TIMESTAMP_NTZ
または CAST を使用して
a_date <= CAST(b_date AS TIMESTAMP_NTZ)
動作の仕組み
- b_dateをJSTの見た目で固定:'2025-12-09 00:00:00 +09:00' $\to$ 2025-12-09 00:00:00 (TIMESTAMP_NTZ)
- JST時刻同士の比較:2025-12-09 00:00:00 $\le$ 2025-12-09 00:00:00
この方法により、タイムゾーンの自動変換が起こらず、「日本の日付・時刻」として単純に大小が比較されます。この例では、期待通りTRUEと判定されます。
まとめ
Snowflakeでタイムスタンプを比較する際は、必ず両方のデータ型を揃えましょう。特に、タイムゾーン付き (TIMESTAMP_TZ) とタイムゾーンなし (TIMESTAMP_NTZ) が混在する場合は注意が必要です。
- JST(見た目の時刻)で比較したい場合:SQL
a_date <= b_date::TIMESTAMP_NTZ
より厳密にUTCで管理・比較したい場合は、両方をTIMESTAMP_TZに変換し、UTCで統一する手法が推奨されますが、簡易的に対応するなら上記の変換が最も手軽です。
タイムスタンプの型変換をマスターして、Snowflakeのデータ処理を快適にしましょう!


