CodeGym /コース /SQL SELF /JSONオブジェクトからデータを取り出す

JSONオブジェクトからデータを取り出す

SQL SELF
レベル 33, レッスン 2
使用可能

JSONBって、ネストされたオブジェクトや配列みたいな複雑なデータ構造を保存できる超便利なツールなんだ。でも、保存するだけじゃ意味ないよね。やっぱりデータを取り出せなきゃ。例えば、usersテーブルのdataカラムに、ユーザーの設定が全部JSONBで入ってるとする。ユーザーがどんなテーマを選んでるか知りたい?それならJSONBオブジェクトから取り出す必要があるよ。

もしJSONBが宝箱なら、->、->>、#>>みたいなオペレーターやjsonb_extract_path()みたいな関数はカギみたいなもん。どうやって使うか見ていこう!

JSONBを扱う基本のオペレーター

PostgreSQLにはJSONBを扱うための主要なオペレーターがいくつか用意されてる。これらを使えば、キーやネストされたオブジェクト、配列から値を取り出せるよ。主なものはこんな感じ:

オペレーター ->

->オペレーターは、指定したキーのオブジェクトや配列を取り出すよ。JSONと同じフォーマットで値が欲しいときはこれを使おう。

例:

-- データ例
SELECT '{"name": "Alice", "age": 25}'::jsonb -> 'name';
-- 結果: "Alice"

オペレーター ->>

->>オペレーターは->に似てるけど、取り出した値をテキストとして返すよ。データをシンプルなテキストで欲しいときに便利!

例:

-- データ例
SELECT '{"name": "Alice", "age": 25}'::jsonb ->> 'age';
-- 結果: "25"(文字列)

オペレーター #>>

#>>オペレーターは、指定したパスでネストされたオブジェクトからデータを取り出すよ。パスはキーの配列で渡す。

例:

-- データ例
SELECT '{"user": {"name": "Bob", "details": {"age": 30}}}'::jsonb #>> '{user, details, age}';
-- 結果: "30"(文字列)

->と->>の違い:

データ型(例えば配列やオブジェクト)をそのまま保持したいなら->を使おう。テキストが欲しいなら->>だね。

JSONBを扱う関数の使い方

jsonb_extract_path()関数は、指定したパスでJSONBオブジェクトから値を取り出すよ。これは#>>オペレーターの関数バージョンみたいなもんだけど、ちょっと表現力が高い。

例:

SELECT jsonb_extract_path('{"user": {"name": "Alice", "settings": {"theme": "dark"}}}'::jsonb, 'user', 'settings', 'theme');
-- 結果: "dark"

もし最初からテキスト値が欲しいなら、jsonb_extract_path_text()を使おう。これはjsonb_extract_path()と同じだけど、返り値が文字列になる。

例:

SELECT jsonb_extract_path_text('{"user": {"name": "Alice", "settings": {"theme": "dark"}}}'::jsonb, 'user', 'settings', 'theme');
-- 結果: dark

実践サンプル

キーで値を取り出す。 例えば、productsテーブルがあって、detailsカラムにJSONBデータが入ってるとしよう:

CREATE TABLE products (
    id SERIAL PRIMARY KEY,
    name TEXT,
    details JSONB
);

INSERT INTO products (name, details) VALUES
    ('Laptop', '{"brand": "Dell", "price": 1200, "specs": {"ram": "16GB", "cpu": "Intel i7"}}'),
    ('Phone', '{"brand": "Apple", "price": 1000, "specs": {"ram": "4GB", "cpu": "A13"}}');

結果:

id name details
1 Laptop {"brand": "Dell", "price": 1200, "specs": {"ram": "16GB", "cpu": "Intel i7"}}
2 Phone {"brand": "Apple", "price": 1000, "specs": {"ram": "4GB", "cpu": "A13"}}

全商品のブランドを取り出す。

SELECT name, details->'brand' AS brand FROM products;

結果:

name brand
Laptop "Dell"
Phone "Apple"

テキスト値を取り出す。 ブランド名をクォートなしで欲しいなら、->>オペレーターを使おう:

SELECT name, details->>'brand' AS brand FROM products;

結果:

name brand
Laptop Dell
Phone Apple

ネストされたデータを取り出す。 各商品のメモリ容量(ram)を取り出してみよう:

SELECT name, details#>>'{specs, ram}' AS ram FROM products;

結果:

name ram
Laptop 16GB
Phone 4GB

パスでデータを取り出す。 同じことをjsonb_extract_path_text()関数でもできるよ:

SELECT name, jsonb_extract_path_text(details, 'specs', 'ram') AS ram FROM products;

結果:

name ram
Laptop 16GB
Phone 4GB

よくあるミスとその回避法

こんなときによくミスしがち:

  • 間違ったパスでデータを取り出そうとする。例えば、キーが存在しない場合はnullになるよ。
  • 目的に合わないオペレーターを使う。->はオブジェクトや配列用、テキストが欲しいなら->>を使おう。

ミスの例:

-- ミス: 'nonexistent'キーは存在しない
SELECT details->>'nonexistent' FROM products;
-- 結果: null

アドバイス:クエリを書く前に、必ずデータ構造をチェックしよう。ミスを防げるよ!

実際のアプリでの使い道

JSONBからデータを取り出すのは、いろんなアプリで使われてるよ:

  • e-commerceで商品のスペックを扱うとき。
  • Webアプリでユーザー設定を保存するとき。
  • 分析でイベントやログみたいな構造化データを処理するとき。

もう一つ例を見てみよう。ordersテーブルに注文データが入ってるとする:

CREATE TABLE orders (
    id SERIAL PRIMARY KEY,
    customer_name TEXT,
    items JSONB
);

INSERT INTO orders (customer_name, items) VALUES
    ('John', '[{"product": "Laptop", "quantity": 1}, {"product": "Mouse", "quantity": 2}]'),
    ('Alice', '[{"product": "Phone", "quantity": 1}]');

注文から全商品の名前を取り出してみよう:

SELECT customer_name, jsonb_array_elements(items)->>'product' AS product FROM orders;

結果:

customer_name product
John Laptop
John Mouse
Alice Phone

このあと、さらにJSONBのネストされたデータや、分析しやすい形への変換も深掘りしていくよ。もっと面白い発見が待ってるから、楽しみにしてて!

2
タスク
SQL SELF, レベル 33, レッスン 2
ロック未解除
`->` 演算子を使ってJSONオブジェクトからデータを抽出する
`->` 演算子を使ってJSONオブジェクトからデータを抽出する
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION