web-dev-qa-db-ja.com

jsonb列から複数の値を抽出して組み合わせる

Postgresのjsonb列から複数の値を抽出しようとしていますが、一部の値がnullに戻るという問題が発生しています。

フィドル

スキーマの設定:

create table jsonb_test (test jsonb);
insert into jsonb_test values('{
"title": "test",
"tags": [
    {"tag": 1},
    {"tag": 2}
]
}'::jsonb);

私が実行しているクエリ:

select jsonb_path_query(test, '$.title'::jsonpath) as title,
       jsonb_path_query(test, '$.tags.tag'::jsonpath) as tag
from jsonb_test

私が探している結果は次のとおりです:

| title | tag |
|-------|-----|
| test  | 1   |
| test  | 2   |

そして私が得ているものは:

| title | tag |
|-------|-----|
| test  | 1   |
| null  | 2   |

クエリでは、nullをなくすために考えられるすべてのことを試しました。同じテーブルではなく、クロス結合から2番目の値のセットを選択し、それを通常の配列に集約してから、ネスト解除などを使用しましたが、私はそれを機能させることができていないようで、さらに重要なことに、その2番目のnullの原因を理解できません。

私が探している結果を得るための最も簡単な方法は何ですか(ここではパフォーマンスが問題になることは想定されていません)。

1
soandos

jsonb_path_query() はセットを返す関数です。 SELECTリストにそれらを複数置く場合、これは予想される動作です。見る:

代わりに CROSS JOIN を探しているようです:

SELECT *
FROM       (SELECT jsonb_path_query(test, '$.title'::jsonpath) AS title FROM jsonb_test) a
CROSS JOIN (SELECT jsonb_path_query(test, '$.tags.tag'::jsonpath) AS tag FROM jsonb_test) b

または、おそらくよりエレガントに、2つのLATERAL結合を使用します。

SELECT a.title, b.tag
FROM   jsonb_test j
     , jsonb_path_query(j.test, '$.title'::jsonpath) a(title)
     , jsonb_path_query(j.test, '$.tags.tag'::jsonpath) b(tag);

db <> fiddle ここ

効果的には、「プロキシクロス結合」。見る:

2