Snowflake VARIANT型のドット記法とFLATTENで半構造化データを自在に扱う

Snowflake VARIANT型のドット記法とFLATTENで半構造化データを自在に扱う Snowflake

はじめに:JSONをSQLで扱うってどういうこと?

「JSONファイルをSnowflakeに取り込んだはいいけど、ネストされた値ってどうやって取り出すの?」——半構造化データに初めて触れた人がぶつかる最初の壁ですよね。実はSnowflakeなら、ドット記法FLATTEN関数という2つの武器を覚えるだけで、JSONをまるでテーブルのように自在に操れるようになります。

この記事では、Snowflake VARIANT型でJSONをロード!半構造化データ入門でロードしたJSONデータを、実際にSELECTして値を取り出すところを一緒に見ていきましょう。

Snowflake VARIANT型のJSONデータにドット記法でアクセスし階層構造の値を取り出す仕組みを示すイメージ図

VARIANT型とドット記法の基本

VARIANT型とは、JSONやXMLのような階層構造を持つデータをそのまま格納できるSnowflake独自のデータ型です。普通の文字列カラムとは違い、中身を「構造化されたオブジェクト」として認識してくれるのがポイント。

そして、その中身にアクセスするのがドット記法です。書き方はとてもシンプルで、JavaScriptでオブジェクトを扱うのと同じ感覚で書けます。

サンプルJSONとドット記法

たとえば、以下のようなJSONが raw_data というVARIANT列に入っているとします。

{
  "user": {
    "id": 101,
    "name": "Taro"
  },
  "items": [
    {"sku": "A-1", "price": 1200},
    {"sku": "B-2", "price": 800}
  ]
}

このとき、ユーザー名を取り出すSQLはこうなります。

SELECT
  raw_data:user.name::STRING       AS user_name,
  raw_data:user.id::NUMBER         AS user_id
FROM orders_raw;

注目してほしいのは2点。コロン(:)で最初のキーにアクセスし、その後はドット(.)でネストを下ること、そして::STRING のように型をキャストすることです。VARIANTのままだと値がダブルクォートで囲まれた状態になるため、明示的に型変換するのが定番テクニックです。

配列を行に展開するFLATTEN関数

では、上のJSONの items のような配列はどう扱うのでしょう?「配列の中の各要素を1行ずつにしたい」というときに登場するのがFLATTENです。LATERAL結合と組み合わせて使います。

SELECT
  raw_data:user.name::STRING  AS user_name,
  f.value:sku::STRING         AS sku,
  f.value:price::NUMBER       AS price
FROM orders_raw,
     LATERAL FLATTEN(input => raw_data:items) f;

これだけで、1件のJSONレコードが商品の数だけ複数行に展開され、普通のリレーショナルテーブルと同じ感覚で扱えるようになります。SnowflakeのSELECT文入門で学んだWHEREやGROUP BYも、もちろんそのまま使えます。

SnowflakeのFLATTEN関数とLATERAL結合でJSON配列を複数行に展開する処理の流れを示すフロー図

FLATTENの便利なオプション

FLATTENには RECURSIVE => TRUE を指定すると、ネストの奥まで一気に展開してくれるオプションもあります。深い階層の配列を扱うときに重宝するので覚えておきましょう。

よくあるユースケースと注意点

  • APIレスポンスのログ分析:WebサービスのアクセスログJSONからユーザーIDやエラーコードだけを取り出す
  • IoTデータの集計:センサー値の配列をFLATTENし、平均や最大値をGROUP BYで算出
  • 注文明細の展開:1注文に複数商品が含まれるECデータを行単位に分解

注意点として、キャストを忘れるとJOINや比較で意図しない動きをすることがあります。数値として比較したいなら必ず ::NUMBER、文字列なら ::STRING を付ける癖をつけましょう。また、キー名は大文字小文字が区別されるのもハマりポイントです。

まとめ

VARIANT型のドット記法とFLATTEN関数を組み合わせれば、JSONなどの半構造化データもSQLだけで完結して扱えます。事前にスキーマ定義をしなくていいので、変化の激しいログデータや外部APIのレスポンスを取り込むときに本領を発揮しますよ。まずは手元のJSONをロードして、SELECT raw:キー名 から試してみてください!

参考リンク

関連記事