web-dev-qa-db-ja.com

Postgresのjsonオブジェクトからキー、値を抽出します

次のような内容のPostgresテーブルがあります。

id  | data

1   | {"a":"4", "b":"5"}
2   | {"a":"6", "b":"7"}
3   | {"a":"8", "b":"9"}

最初の列は整数で、2番目の列はjson列です。

JSONからキーと値を展開できるようにしたいので、結果は次のようになります。

id  | key  | value

1   | a    | 4
1   | b    | 5
2   | a    | 6
2   | b    | 7
3   | a    | 8
3   | b    | 9

これはPostgres SQLで実現できますか?


私が試したもの

元のテーブルを次のようにシミュレートできると仮定します。

select *
from 
(
values
(1, '{"a":"4", "b":"5"}'::json),
(2, '{"a":"6", "b":"7"}'::json),
(3, '{"a":"8", "b":"9"}'::json)
) as q (id, data)

以下を使用してキーのみを取得できます。

select id, json_object_keys(data::json)
from 
(
values
(1, '{"a":"4", "b":"5"}'::json),
(2, '{"a":"6", "b":"7"}'::json),
(3, '{"a":"8", "b":"9"}'::json)
) as q (id, data)

そして、次のようなレコードセットとして取得できます。

select id, json_each(data::json)
from 
(
values
(1, '{"a":"4", "b":"5"}'::json),
(2, '{"a":"6", "b":"7"}'::json),
(3, '{"a":"8", "b":"9"}'::json)
) as q (id, data)

しかし、ID、キー、値を使用して結果を達成する方法を見つけることはできません。

何か案は?

注:私が使用している実際のjsonは、これよりもかなりネストされていますが、この例は私の根本的な問題をよく表していると思います。

11
Tom G
_SELECT q.id, d.key, d.value
FROM q
JOIN json_each_text(q.data) d ON true
ORDER BY 1, 2;
_

関数json_each_text()はセットを返す関数なので、行ソースとして使用する必要があります。関数の出力はここにあります 横方向に結合 テーブルqに、つまりテーブルの各行に対して、dataからの各_(key, value)_ペアを意味します列はその行のみに結合されるため、元の行とjsonオブジェクトから形成される行との関係は維持されます。

テーブルqは、非常に複雑なサブクエリ(または質問のようにVALUES句)になることもあります。関数では、そのサブクエリの評価結果から適切な列が使用されるため、サブクエリのエイリアスとサブクエリの(エイリアス)列への参照のみを使用します。

19
Patrick