本文へ移動
SQLTreasure Data / CDP 更新日: 2026年5月24日 約5分で読めます

Hiveはfalse、Trinoはtrueになる理由|整数除算の落とし穴

「同じクエリなのに、結果が違う」

日付を整数で管理している現場では、こんなクエリをよく書く。

SELECT ( 20250515 / 100 ) <= 202505

20250515(yyyymmdd形式の日付)を 100 で割って月(yyyymm)に変換し、202505 と比較する。
一見シンプルな式だ。

ところがこのクエリ、実行するSQLエンジンによって結果が変わる。

エンジン結果
Hivefalse
Trinotrue

「バグか?」と焦るが、バグではない。
整数どうしの除算(/)に対する型の扱いが、エンジンごとに根本的に異なるからだ。


なぜ結果が変わるのか

答えはシンプルで、20250515 / 100 の計算結果の型が違う。

Hive の場合:浮動小数点除算

Hive は整数どうしの /DOUBLE(浮動小数点数)として計算する。

20250515 / 100 = 202505.15 (DOUBLE)

その結果と 202505(INTEGER)を比較すると、

202505.15 <= 202505 → false

202505.15202505 より大きいので、false になる。

Trino の場合:整数除算(切り捨て)

Trino は整数どうしの /INTEGER として計算し、小数点以下を切り捨てる。

20250515 / 100 = 202505 (INTEGER、余り切り捨て)

その結果と 202505(INTEGER)を比較すると、

202505 <= 202505 → true

同じ値どうしの比較になるので、true になる。

まとめると

エンジン20250515 / 100 の結果<= 202505 の評価
Hive202505.15DOUBLEfalse
Trino202505INTEGERtrue

仕様として正しいか

どちらが「間違い」ということはなく、SQL標準の解釈の違いだ。

ANSI SQL は整数どうしの除算について厳密な規定を設けておらず、実装に委ねている部分がある。Hive は BigQuery に近い「精度を失わない」方向の実装、Trino(旧 PrestoSQL)は多くのプログラミング言語(Python, Java, C など)と同じ「整数除算は整数で返す」方向の実装をとっている。

どちらが直感に近いかは人によるが、実務で引っかかりやすいのは確かだ。


実務でよく踏む場面

この挙動が問題になるのは、日付を整数で持っているテーブルで「日付 → 月」に変換するときだ。

SELECT *
FROM orders
WHERE ( order_date_int / 100 ) <= 202505

Hive ベースの Treasure Data でこれを実行すると、order_date_int / 100 は DOUBLE になる。
整数で持つ月(202505)との比較は微妙にずれるため、意図通りに絞り込めないことがある。


安全な書き方:CAST で型を明示する

エンジンに依存しない書き方にするには、CAST で明示的に整数に変換してから比較する。

-- 安全な書き方(Hive / Trino 共通)
SELECT ( CAST( 20250515 AS BIGINT ) / 100 ) <= 202505

CAST( 20250515 AS BIGINT ) / 100 は Hive でも Trino でも整数除算になり、結果は 202505(INTEGER)になる。

202505 <= 202505 → true (両エンジン共通)

あるいは、そもそも除算で月変換するのをやめて、文字列操作や専用の日付関数を使う方法もある。

-- 文字列 LEFT で月部分を切り出す(Hive / Trino 共通)
SELECT LEFT( CAST( 20250515 AS VARCHAR ), 6 )  -- '202505'

-- TD_TIME_FORMAT を使う(Treasure Data 環境)
SELECT TD_TIME_FORMAT( TD_DATE_TRUNC( 'month', time ), 'yyyyMM', 'JST' )

Treasure Data(Hive/Trino 混在環境)での注意点

同じクエリを Hive と Trino で使い回している場合、このような型の挙動の違いでサイレントに結果が変わるリスクがある。

特に次のようなケースで踏みやすい。

  • 日付を yyyymmdd の整数で持つテーブルを /100 で月変換しているとき
  • セグメント条件に INT列 / N の比較を使っているとき
  • Hive で書いたクエリを Trino に移行したとき

移行時は、数値リテラルどうしの除算が含まれる箇所を優先的に確認することを勧める。


まとめ

確認ポイントHiveTrino
整数 / 整数 の型DOUBLE(浮動小数点)INTEGER(切り捨て)
20250515 / 100 の値202505.15202505
<= 202505 の評価falsetrue
安全な対処法CAST で整数に変換CAST で整数に変換

同じ SQL が異なるエンジンでサイレントに違う結果を返すのは、デバッグが難しいバグの温床になる。
整数除算を使うときは CAST で型を明示し、エンジンに依存しないクエリを書く習慣をつけておこう。


次のアクション

SQLやデータ活用を、手元で試しながら理解する

記事で読んだ考え方を、SQL練習場や関連カテゴリの記事でさらに深掘りできます。相談やご依頼もお問い合わせページから受け付けています。

SQL練習場で試す お問い合わせ

この記事を書いた人:martechfarm

Treasure Data Top Lapidarist Award受賞。

SQL / Digdag / Python / CDP設計 / CRM設計を横断し、企業のデータ活用を支援。

実績・支援内容を見る →

MarTech Farmをもっと見る

今すぐ購読し、続きを読んで、すべてのアーカイブにアクセスしましょう。

続きを読む