Snowflake

Snowflake半構造化データ処理

2026-03-21
更新: 2026-03-27
NicheeLab編集部

SnowflakeはVARIANT型を中心に、JSON・Parquet・Avro・ORC・XMLといった半構造化データをリレーショナルテーブル内にネイティブに格納し、SQLで直接クエリできます。コロン表記(:)によるパスアクセス、LATERAL FLATTENによる配列展開、OBJECT_CONSTRUCT/ARRAY_AGGによる構築が試験で頻出の3大操作パターンです。

VARIANT型の基礎

VARIANT型はJSON・オブジェクト・配列・スカラー値などあらゆる半構造化データを格納できる汎用型です。最大16MBのデータを1値に格納でき、内部的には列指向形式で圧縮保存されます。

半構造化型格納できるデータ用途
VARIANT任意の半構造化データ(JSON / オブジェクト / 配列 / スカラー)最も汎用的。JSONロードの受け皿
OBJECTキーバリューペアの集合構造が既知のJSON Object
ARRAY順序付きの値の配列リスト・タグ・配列データ
-- VARIANTカラムを持つテーブルの作成
CREATE OR REPLACE TABLE raw.events (
  event_id   INT AUTOINCREMENT,
  received_at TIMESTAMP_NTZ DEFAULT CURRENT_TIMESTAMP(),
  payload    VARIANT
);

-- JSONデータの直接INSERT
INSERT INTO raw.events (payload)
SELECT PARSE_JSON('{
  "user_id": 42,
  "action": "purchase",
  "items": [
    {"sku": "A100", "qty": 2, "price": 1500},
    {"sku": "B200", "qty": 1, "price": 3200}
  ],
  "metadata": {"source": "web", "version": "2.1"}
}');

コロン表記(:)によるパスアクセス

VARIANT型のデータにはコロン表記(:)でキーを指定してアクセスします。ネストしたオブジェクトにはドット(.)、配列要素にはブラケット([])を使います。

-- 第1階層のキーアクセス
SELECT
  payload:user_id::INT       AS user_id,
  payload:action::STRING     AS action
FROM raw.events;

-- ネストしたオブジェクトのアクセス
SELECT
  payload:metadata.source::STRING  AS source,
  payload:metadata.version::STRING AS api_version
FROM raw.events;

-- 配列要素へのアクセス(0始まりインデックス)
SELECT
  payload:items[0].sku::STRING   AS first_sku,
  payload:items[0].price::NUMBER AS first_price
FROM raw.events;

::(キャスト演算子)を使って明示的に型変換を行わないと、結果はVARIANT型のまま返されます。WHERE句やJOINで使用する場合は必ずキャストが必要です。

LATERAL FLATTENによる配列展開

LATERAL FLATTENは、VARIANT型内の配列やオブジェクトを行に展開する関数です。JSONの配列要素を1行ずつリレーショナル形式に変換する際の標準的な手法です。

-- 配列内の各アイテムを行に展開
SELECT
  e.event_id,
  e.payload:user_id::INT    AS user_id,
  f.index                   AS item_index,
  f.value:sku::STRING       AS sku,
  f.value:qty::INT          AS quantity,
  f.value:price::NUMBER     AS price
FROM raw.events e,
  LATERAL FLATTEN(INPUT => e.payload:items) f;

FLATTENの出力カラム

カラム名説明
SEQ入力レコードのシーケンス番号
KEYオブジェクトのキー名(配列の場合はNULL)
PATH要素へのパス文字列
INDEX配列のインデックス(0始まり)
VALUE展開された値(VARIANT型)
THIS展開元の配列/オブジェクト全体

多段ネストの展開

-- 2段ネストの展開(orders → items)
SELECT
  o.value:order_id::INT      AS order_id,
  i.value:product::STRING    AS product,
  i.value:amount::NUMBER     AS amount
FROM raw.batch_data d,
  LATERAL FLATTEN(INPUT => d.payload:orders) o,
  LATERAL FLATTEN(INPUT => o.value:items) i;

OBJECT_CONSTRUCTによるオブジェクト構築

OBJECT_CONSTRUCTは、リレーショナルカラムからVARIANT型のJSONオブジェクトを構築する関数です。データのアンロード(JSON形式でのエクスポート)やAPI連携用のペイロード生成に活用します。

-- リレーショナルデータからJSONオブジェクトを構築
SELECT OBJECT_CONSTRUCT(
  'order_id',   o.order_id,
  'customer',   o.customer_name,
  'total',      o.total_amount,
  'order_date', o.order_date::STRING
) AS order_json
FROM analytics.orders o
WHERE o.order_date = '2026-03-27';

-- OBJECT_CONSTRUCT_KEEP_NULL(NULLキーを保持)
SELECT OBJECT_CONSTRUCT_KEEP_NULL(
  'name',  e.name,
  'email', e.email,
  'phone', e.phone
) AS employee_json
FROM hr.employees e;

ARRAY_AGGによる配列集約

ARRAY_AGGは、複数行の値を1つのARRAY型に集約する関数です。GROUP BYと組み合わせて、リレーショナルデータを非正規化JSON構造に変換する際に使用します。

-- 顧客ごとの注文IDリストを配列に集約
SELECT
  customer_id,
  ARRAY_AGG(DISTINCT order_id) WITHIN GROUP (ORDER BY order_date)
    AS order_ids,
  ARRAY_SIZE(ARRAY_AGG(DISTINCT order_id)) AS order_count
FROM analytics.orders
GROUP BY customer_id;

-- OBJECT_CONSTRUCTとARRAY_AGGの組み合わせ
SELECT OBJECT_CONSTRUCT(
  'customer_id', customer_id,
  'orders', ARRAY_AGG(
    OBJECT_CONSTRUCT(
      'order_id', order_id,
      'amount',   total_amount
    )
  )
) AS customer_orders_json
FROM analytics.orders
GROUP BY customer_id;

半構造化データのロードパターン

JSONファイルのロードでは、STRIP_OUTER_ARRAYオプションで最外部の配列を行に分解するパターンが頻出です。

-- JSON File Formatの定義
CREATE OR REPLACE FILE FORMAT json_format
  TYPE = JSON
  STRIP_OUTER_ARRAY = TRUE
  ALLOW_DUPLICATE = FALSE;

-- ステージからVARIANTカラムへロード
COPY INTO raw.events (payload)
FROM @data_stage/events/
FILE_FORMAT = json_format;

-- Parquetファイルのロード(スキーマ自動検出)
COPY INTO raw.parquet_data
FROM @data_stage/parquet/
FILE_FORMAT = (TYPE = PARQUET)
MATCH_BY_COLUMN_NAME = CASE_INSENSITIVE;

その他の主要関数

関数用途使用例
PARSE_JSON文字列→VARIANT変換PARSE_JSON('{"key":"val"}')
TO_JSONVARIANT→JSON文字列変換TO_JSON(payload)
ARRAY_SIZE配列の要素数を取得ARRAY_SIZE(payload:items)
ARRAY_CONTAINS配列内の値の存在チェックARRAY_CONTAINS('A100'::VARIANT, payload:skus)
OBJECT_KEYSオブジェクトのキー一覧を配列で取得OBJECT_KEYS(payload:metadata)
GET_PATH / GETパス文字列でVARIANT要素を取得GET_PATH(payload, 'metadata.source')
TYPEOFVARIANT値の内部型を確認TYPEOF(payload:user_id)

問題で確認

Semi-structured Data

問題 1

VARIANT型カラム payload に格納されたJSONの配列 payload:items を展開し、各要素の sku と price を取得したい。正しいSQLはどれか。

  1. SELECT f.value:sku, f.value:price FROM events, LATERAL FLATTEN(INPUT => payload:items) f
  2. SELECT payload:items.sku, payload:items.price FROM events
  3. SELECT SPLIT(payload:items, ',') AS sku, price FROM events
  4. SELECT PARSE_JSON(payload:items):sku, PARSE_JSON(payload:items):price FROM events

正解: A

VARIANT型内の配列を行に展開するにはLATERAL FLATTENを使用します。展開された各要素はf.valueでアクセスし、f.value:skuのようにコロン表記でキーを指定します。payload:items.skuは配列全体に対するプロパティアクセスとなり、期待した結果は得られません。SPLITは文字列分割関数であり、VARIANT配列の展開には使えません。

よくある質問

VARIANT型のカラムに格納できるデータサイズの上限はありますか?

VARIANT型の1つの値の最大サイズは16MBです。ただしVARIANTカラムを含むマイクロパーティション全体のサイズ制約もあるため、実運用では1レコードあたり数MB以内に収めることが推奨されます。巨大なJSONドキュメントをそのまま格納するよりも、LATERAL FLATTENで正規化して別テーブルに分解する設計が、クエリパフォーマンスとコストの両面で有利です。

VARIANT型に対するクエリはリレーショナルカラムと同等のパフォーマンスが出ますか?

SnowflakeはVARIANT型のデータを内部的に列指向形式でメタデータ(型情報・パス情報)とともに格納するため、頻繁にアクセスされるキーについては高速なアクセスが可能です。ただし、コロン表記(:)やブラケット表記([])による半構造化パスの評価はリレーショナルカラムのスキャンよりオーバーヘッドがあります。頻繁にフィルタリング・JOIN・集約に使うキーはVIEWやCTASで事前に抽出してリレーショナルカラムに変換するのがベストプラクティスです。

FLATTENでネストが深い配列を展開するにはどうしますか?

LATERAL FLATTENは1段階のネスト展開を行うため、複数段のネストには複数回のLATERAL FLATTENをチェーンします。例えばorders[].items[].tags[]のような3段ネストの場合、FROM raw, LATERAL FLATTEN(raw.data:orders) o, LATERAL FLATTEN(o.value:items) i, LATERAL FLATTEN(i.value:tags) tのように記述します。各FLATTEN結果はvalueカラムで次のFLATTENに渡せます。

この記事で学んだ内容を問題で確認しましょう

16,000問以上の問題で実力チェック

無料で問題を解いてみる
この記事の著者

NicheeLab編集部

データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。


関連記事
Snowflake

Snowflake資格一覧|全11試験(SnowPro)の難易度・費用

Snowflake認定資格(SnowPro)全11試験の一覧・難易度・費用・出題範囲を徹底解説。...

Snowflake

Snowflake試験の難易度ランキング|全11資格を徹底比較

Snowflake(SnowPro)認定全11試験の難易度をランキング形式で比較。学習時間・合格に必要なスキルから分析。...

Snowflake

Snowflake資格の勉強方法|効率的な学習ルートと合格のコツ

Snowflake認定資格(SnowPro)に最短で合格するための勉強方法。公式リソース・学習スケジュールを徹底ガイド。...

Snowflake

SnowPro Core試験完全解説|出題範囲・問題例・合格戦略

SnowPro Core Certification(COF-C03)を徹底解説。出題範囲・100問の試験形式・合格ライ...

Snowflake

SnowPro Platform Associate完全解説|入門試験の攻略

SnowPro Associate: Platform Certification(SOL-C01)を徹底解説。最も簡単...

Snowflakeの記事一覧 (102件)
© 2026 NicheeLab All rights reserved.