他のバージョンの文書 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9.6 | 9.5 | 9.4 | 9.3 | 9.2 | 9.1 | 9.0 | 8.4 | 8.3 | 8.2 | 8.1 | 8.0 | 7.4 | 7.3 | 7.2

9.16. JSON関数と演算子 #

この節では次のことを説明します。

SQL環境内のJSONデータ型にネイティブサポートを提供するために、PostgreSQLSQL/JSONデータモデルを実装しています。 このモデルは、一連の項目で構成されます。 各項目は、SQLスカラ値、追加のSQL/JSON NULL値、およびJSON配列とオブジェクトを使用する複合データ構造を保持できます。 モデルは、JSON規格RFC 7159で暗黙的に指定されているデータモデルを形式化したものです。

SQL/JSONでは、トランザクションをサポートをしながら、通常のSQLデータと一緒にJSONデータをハンドルすることができます。以下のものが含まれます:

SQL/JSON標準を更に学ぶためには、[sqltr-19075-6]をご覧ください。 PostgreSQLでサポートされているJSON型の詳細に関しては、8.14をご覧ください。

9.16.1. JSONデータの処理と生成 #

表 9.45にJSONデータ型(8.14を参照)で使用可能な演算子を示します。 加えて表 9.1で示す通常の比較演算子がjsonbで利用できますが、jsonでは利用できません。 比較演算子は8.14.4で概要が示されているように示すBツリー操作用の順序付け規則にしたがいます。 レコードの値をJSONに集約するjson_agg集約関数、値の対をJSONオブジェクトに集約するjson_object_agg集約関数、およびそれらのjsonb版のjsonb_aggjsonb_object_aggについては9.21も参照して下さい。

表9.45 jsonjsonb演算子

演算子

説明

json -> integerjson

jsonb -> integerjsonb

JSON配列のn番目の要素を取り出します。 (配列要素はゼロから始まりますが、負の整数は最後から数えられます。)

'[{"a":"foo"},{"b":"bar"},{"c":"baz"}]'::json -> 2{"c":"baz"}

'[{"a":"foo"},{"b":"bar"},{"c":"baz"}]'::json -> -3{"a":"foo"}

json -> textjson

jsonb -> textjsonb

与えられたキーでJSONオブジェクトフィールドを取り出します。

'{"a": {"b":"foo"}}'::json -> 'a'{"b":"foo"}

json ->> integertext

jsonb ->> integertext

JSON配列のn番目の要素をtextとして取り出します。

'[1,2,3]'::json ->> 23

json ->> texttext

jsonb ->> texttext

与えられたキーでJSONオブジェクトフィールドをtextとして取り出します。

'{"a":1,"b":2}'::json ->> 'b'2

json #> text[]json

jsonb #> text[]jsonb

指定したパスにおけるJSONの副オブジェクトを取り出します。パス要素はフィールドキーあるいは配列のインデックスでも構いません。

'{"a": {"b": ["foo","bar"]}}'::json #> '{a,b,1}'"bar"

json #>> text[]text

jsonb #>> text[]text

指定したパスにおけるJSONの副オブジェクトをtextとして取り出します。

'{"a": {"b": ["foo","bar"]}}'::json #>> '{a,b,1}'bar


注記

JSON入力が要求と一致する正しい構造をしていなければ、フィールド/要素/パス抽出演算子は失敗するのではなくNULLを返します。例えばそのような要素が存在しない場合です。

ほかにjsonbだけで利用可能な演算子もいくつか存在します。 それらを表 9.46に示します。 8.14.4には、インデックス付されたjsonbデータを効率的に検索するためにこれらの演算子をどのように利用できるかについて書いてあります。

表9.46 追加jsonb演算子

演算子

説明

jsonb @> jsonbboolean

最初のJSON値は二番目を含んでいるか? (包含の詳細は8.14.3を参照してください。)

'{"a":1, "b":2}'::jsonb @> '{"b":2}'::jsonbt

jsonb <@ jsonbboolean

最初のJSON値は二番目に含まれているか?

'{"b":2}'::jsonb <@ '{"a":1, "b":2}'::jsonbt

jsonb ? textboolean

そのテキスト文字列はトップレベルのキーあるいは配列要素としてJSON値中に存在しているか?

'{"a":1, "b":2}'::jsonb ? 'b't

'["a", "b", "c"]'::jsonb ? 'b't

jsonb ?| text[]boolean

テキスト配列中のどれかの文字列がトップレベルのキーあるいは配列要素として存在しているか?

'{"a":1, "b":2, "c":3}'::jsonb ?| array['b', 'd']t

jsonb ?& text[]boolean

テキスト配列のすべての文字列がトップレベルのキーあるいは配列要素として存在しているか?

'["a", "b", "c"]'::jsonb ?& array['a', 'b']t

jsonb || jsonbjsonb

2つのjsonb値を結合します。 2つの配列を結合するとそれらのキーの和を持つ配列を生成します。 キーが重複している場合は2番目のオブジェクトの値が使用されます。 それ以外の場合には非配列入力を単一の要素を持つ配列に変換し、次に2つの配列として取り扱います。 再帰操作は行いません。トップレベルの配列あるいはオブジェクト構造だけがマージされます。

'["a", "b"]'::jsonb || '["a", "d"]'::jsonb["a", "b", "a", "d"]

'{"a": "b"}'::jsonb || '{"c": "d"}'::jsonb{"a": "b", "c": "d"}

'[1, 2]'::jsonb || '3'::jsonb[1, 2, 3]

'{"a": "b"}'::jsonb || '42'::jsonb[{"a": "b"}, 42]

一つの要素を持つとして配列を他の配列に追加するには、例のように配列の追加のレイヤ中に含めてください。

'[1, 2]'::jsonb || jsonb_build_array('[3, 4]'::jsonb)[1, 2, [3, 4]]

jsonb - textjsonb

キー(及びその値)をJSONオブジェクトから削除します。あるいはマッチする文字列値をJSON配列から削除します。

'{"a": "b", "c": "d"}'::jsonb - 'a'{"c": "d"}

'["a", "b", "c", "b"]'::jsonb - 'b'["a", "c"]

jsonb - text[]jsonb

左のオペランドからマッチするすべてのキーあるいは配列要素を削除します。

'{"a": "b", "c": "d"}'::jsonb - '{a,c}'::text[]{}

jsonb - integerjsonb

指定したインデックス(負の整数は最後から数えます)の配列要素を削除します。 JSON値が配列でなければエラーが生じます。

'["a", "b"]'::jsonb - 1 ["a"]

jsonb #- text[]jsonb

指定パスのフィールドあるいは配列要素を削除します。パス要素はフィールドキーあるいは配列インデックスが指定できます。

'["a", {"b":1}]'::jsonb #- '{1,b}'["a", {}]

jsonb @? jsonpathboolean

JSONパスは指定されたJSON値に対して何らかの項目を返すか?(これは標準SQLのJSONパス式でのみ有用であり、述語チェック式では有効ではありません。述語チェック式は常に値を返すからです。)

'{"a":[1,2,3,4,5]}'::jsonb @? '$.a[*] ? (@ > 2)'t

jsonb @@ jsonpathboolean

指定されたJSON値に対するJSONパス述語チェックの結果を返します(これは、標準SQLのJSONパス式ではなく、述部チェック式でのみ有用です。パス結果が単一のブール値でない場合はNULLを返すためです)。

'{"a":[1,2,3,4,5]}'::jsonb @@ '$.a[*] > 2't


注記

jsonpath演算子の@?および@@演算子は以下のエラーを抑止します。 オブジェクトフィールドあるいは配列要素の欠如、期待しないJSON要素型、日付時刻及び数値エラー。 以下に示すjsonpath関連の関数もこれらのエラーを抑止するようにすることもできます。 この振る舞いは、異なる構造のJSON文書集合を検索する際に役に立つかも知れません。

表 9.47に、json値およびjsonb値を作成するために利用可能な関数を示します。 このテーブルの一部の関数は、返されるデータ型を指定するRETURNING句を持っています。 これはjsonjsonbbytea、文字列型(textcharvarchar)、あるいはjsonからその型へのキャストがある型のいずれかでなければなりません。 デフォルトではjson型が返されます。

表9.47 JSON作成関数

関数

説明

to_json ( anyelement ) → json

to_jsonb ( anyelement ) → jsonb

SQL値をjsonあるいはjsonbに変換します。 配列と複合型は再帰的に配列とオブジェクトに変換されます。(多次元配列はJSONにおける配列の配列になります。) それ以外は、そのSQLデータ型からjsonにキャストがあれば、キャスト関数が変換のために用いられます。[a] そうでなければスカラJSON値が生成されます。 数値、論理値、NULL以外のスカラには、有効なJSON文字列値にするための必要なエスケープ処理が施されたテキスト表現が使われます。

to_json('Fred said "Hi."'::text)"Fred said \"Hi.\""

to_jsonb(row(42, 'Fred said "Hi."'::text)){"f1": 42, "f2": "Fred said \"Hi.\""}

array_to_json ( anyarray [, boolean ] ) → json

SQL配列をJSON配列に変換します。 追加の論理引数が真であるときに改行がトップレベルの配列要素の間に加えられる以外は、その振る舞いはto_jsonと同じです。

array_to_json('{{1,5},{99,100}}'::int[])[[1,5],[99,100]]

json_array ( [ { value_expression [ FORMAT JSON ] } [, ...] ] [ { NULL | ABSENT } ON NULL ] [ RETURNING data_type [ FORMAT JSON [ ENCODING UTF8 ] ] ])

json_array ( [ query_expression ] [ RETURNING data_type [ FORMAT JSON [ ENCODING UTF8 ] ] ])

JSON配列を、一連のvalue_expression引数、またはquery_expressionの結果のいずれかから構成します。 query_expressionは、単一の列を返すSELECT問い合わせである必要があります。 ABSENT ON NULLが指定されている場合、NULL値は無視されます。 query_expressionが使用されている場合、常にそうなります。

json_array(1,true,json '{"a":null}')[1, true, {"a":null}]

json_array(SELECT * FROM (VALUES(1),(2)) t)[1, 2]

row_to_json ( record [, boolean ] ) → json

SQL複合値をJSONオブジェクトに変換します。 追加の論理引数が真であるときに改行がトップレベルの配列要素の間に加えられる以外は、その振る舞いはto_jsonと同じです。

row_to_json(row(1,'foo')){"f1":1,"f2":"foo"}

json_build_array ( VARIADIC "any" ) → json

jsonb_build_array ( VARIADIC "any" ) → jsonb

異なる型から構成される可能性のあるJSON配列をvariadic引数リストから作成します。 各々の引数はto_jsonあるいはto_jsonbに従って変換されます。

json_build_array(1, 2, 'foo', 4, 5)[1, 2, "foo", 4, 5]

json_build_object ( VARIADIC "any" ) → json

jsonb_build_object ( VARIADIC "any" ) → jsonb

variadic引数リストからJSONオブジェクトを作成します。 慣例により引数リストは代替キーと値が交互に並んだものです。 キー引数はテキストに強制的に変換されます。 値引数はto_jsonあるいはto_jsonbに従って変換されます。

json_build_object('foo', 1, 2, row(3,'bar')){"foo" : 1, "2" : {"f1":3,"f2":"bar"}}

json_object ( [ { key_expression { VALUE | ':' } value_expression [ FORMAT JSON [ ENCODING UTF8 ] ] }[, ...] ] [ { NULL | ABSENT } ON NULL ] [ { WITH | WITHOUT } UNIQUE [ KEYS ] ] [ RETURNING data_type [ FORMAT JSON [ ENCODING UTF8 ] ] ])

指定されたすべてのキー/値ペアのJSONオブジェクトを構築します。 キー/値ペアが指定されていない場合は、空のオブジェクトを構築します。 key_expressionは、textタイプに変換されるJSONキーを定義するスカラ式です。 NULLにすることも、JSONタイプにキャストを持つタイプに属することもできません。 WITH UNIQUE KEYSが指定されている場合は、重複key_expressionがあってはなりません。 ABSENT ON NULLが指定されている場合、NULLと評価されるvalue_expressionは出力から除外されます。 NULL ON NULLが指定されているか、その句が省略されている場合、キーはNULLの値で含まれます。

json_object('code' VALUE 'P123', 'title': 'Jaws'){"code" : "P123", "title" : "Jaws"}

json_object ( text[] ) → json

jsonb_object ( text[] ) → jsonb

テキスト配列からJSONオブジェクトを作成します。 配列は、偶数個の要素からなる1次元(キー/値の対が交互に並んでいるものと扱われます)あるいは内側の配列が2つの要素を持つ2次元(2つの要素がキー/値のペアとして扱われます)のいずれかでなければなりません。 すべての値はJSON文字列に変換されます。

json_object('{a, 1, b, "def", c, 3.5}'){"a" : "1", "b" : "def", "c" : "3.5"}

json_object('{{a, 1}, {b, "def"}, {c, 3.5}}'){"a" : "1", "b" : "def", "c" : "3.5"}

json_object ( keys text[], values text[] ) → json

jsonb_object ( keys text[], values text[] ) → jsonb

この形のjson_objectは2つの別々の配列からキーと値の対を取ります。 他の点ではすべて、引数1つの形と同じです。

json_object('{a,b}', '{1,2}'){"a": "1", "b": "2"}

json ( expression [ FORMAT JSON [ ENCODING UTF8 ]] [ { WITH | WITHOUT } UNIQUE [ KEYS ]] ) → json

指定されたtextまたはbytea文字列(UTF8エンコーディング)をJSON値に変換します。 expressionがNULLの場合、SQLのNULL値が返されます。 WITH UNIQUEが指定された場合、expressionは重複するオブジェクトキーを含んではなりません。

json('{"a":123, "b":[true,"foo"], "a":"bar"}'){"a":123, "b":[true,"foo"], "a":"bar"}

json_scalar ( expression )

指定されたSQLスカラ値をJSONスカラ値に変換します。 入力がNULLの場合、SQLのNULLが返されます。 入力が数値またはブール値の場合、対応するJSONの数値またはブール値が返されます。 それ以外の場合は、JSONの文字列が返されます。

json_scalar(123.45)123.45

json_scalar(CURRENT_TIMESTAMP)"2022-05-10T10:51:04.62128-04:00"

json_serialize ( expression [ FORMAT JSON [ ENCODING UTF8 ] ] [ RETURNING data_type [ FORMAT JSON [ ENCODING UTF8 ] ] ] )

SQL/JSON式を文字列またはバイナリ文字列に変換します。 expressionは、任意のJSON型、任意の文字列型、またはUTF8エンコーディングのbyteaです。 RETURNINGで使用される戻り型は、任意の文字列型またはbyteaです。 デフォルトはtextです。

json_serialize('{ "a" : 1 } ' RETURNING bytea)\x7b20226122203a2031207d20

[a] たとえばhstore拡張にはhstoreからjsonへのキャストがあり、JSON生成関数で変換されたhstore値は、原始的な文字列値としてではなく、JSONオブジェクトとして表示されます。


表 9.48には、JSONをテストするためのSQL/JSON機能の詳細が記載されています。

表9.48 SQL/JSONテスト用関数

関数の呼び出し形式

説明

expression IS [ NOT ] JSON [ { VALUE | SCALAR | ARRAY | OBJECT } ] [ { WITH | WITHOUT } UNIQUE [ KEYS ] ]

この述語は、expressionが指定された型のJSONとして解析できるかどうかをテストします。 SCALARARRAY、またはOBJECTが指定されている場合、テストはJSONがその特定の型のものであるかどうかを示します。 WITH UNIQUE KEYSが指定されている場合、expressionのオブジェクトもテストされ、重複キーがあるかどうかが確認されます。

SELECT js,
  js IS JSON "json?",
  js IS JSON SCALAR "scalar?",
  js IS JSON OBJECT "object?",
  js IS JSON ARRAY "array?"
FROM (VALUES
      ('123'), ('"abc"'), ('{"a": "b"}'), ('[1,2]'),('abc')) foo(js);
     js     | json? | scalar? | object? | array?
------------+-------+---------+---------+--------
 123        | t     | t       | f       | f
 "abc"      | t     | t       | f       | f
 {"a": "b"} | t     | f       | t       | f
 [1,2]      | t     | f       | f       | t
 abc        | f     | f       | f       | f

SELECT js,
  js IS JSON OBJECT "object?",
  js IS JSON ARRAY "array?",
  js IS JSON ARRAY WITH UNIQUE KEYS "array w. UK?",
  js IS JSON ARRAY WITHOUT UNIQUE KEYS "array w/o UK?"
FROM (VALUES ('[{"a":"1"},
 {"b":"2","b":"3"}]')) foo(js);
-[ RECORD 1 ]-+--------------------
js            | [{"a":"1"},        +
              |  {"b":"2","b":"3"}]
object?       | f
array?        | t
array w. UK?  | f
array w/o UK? | t


表 9.49jsonjsonb値を処理するのに使える関数を示します。

表9.49 JSON処理関数

関数

説明

json_array_elements ( json ) → setof json

jsonb_array_elements ( jsonb ) → setof jsonb

トップレベルのJSON配列をJSON値の集合に展開します。

select * from json_array_elements('[1,true, [2,false]]')

   value
-----------
 1
 true
 [2,false]

json_array_elements_text ( json ) → setof text

jsonb_array_elements_text ( jsonb ) → setof text

トップレベルのJSON配列をtext値の集合に展開します。

select * from json_array_elements_text('["foo", "bar"]')

   value
-----------
 foo
 bar

json_array_length ( json ) → integer

jsonb_array_length ( jsonb ) → integer

トップレベルのJSON配列の要素数を返します。

json_array_length('[1,2,3,{"f1":1,"f2":[5,6]},4]')5

jsonb_array_length('[]')0

json_each ( json ) → setof record ( key text, value json )

jsonb_each ( jsonb ) → setof record ( key text, value jsonb )

トップレベルのJSONオブジェクトをキー/値のペアの集合に展開します。

select * from json_each('{"a":"foo", "b":"bar"}')

 key | value
-----+-------
 a   | "foo"
 b   | "bar"

json_each_text ( json ) → setof record ( key text, value text )

jsonb_each_text ( jsonb ) → setof record ( key text, value text )

トップレベルのJSONオブジェクトをキー/値のペアの集合に展開します。 返り値のvaluetext型です。

select * from json_each_text('{"a":"foo", "b":"bar"}')

 key | value
-----+-------
 a   | foo
 b   | bar

json_extract_path ( from_json json, VARIADIC path_elems text[] ) → json

jsonb_extract_path ( from_json jsonb, VARIADIC path_elems text[] ) → jsonb

指定したパスにおけるJSONの副オブジェクトを取り出します。 (これは#>演算子と機能的に同じですが、パスをvariadicリストで書き出す方がより便利な場合があります。)

json_extract_path('{"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}', 'f4', 'f6')"foo"

json_extract_path_text ( from_json json, VARIADIC path_elems text[] ) → text

jsonb_extract_path_text ( from_json jsonb, VARIADIC path_elems text[] ) → text

指定したパスにおけるJSONの副オブジェクトをtextとして取り出します。 (これは機能的には#>>演算子と同じです。)

json_extract_path_text('{"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}', 'f4', 'f6')foo

json_object_keys ( json ) → setof text

jsonb_object_keys ( jsonb ) → setof text

トップレベルのJSONオブジェクト中のキーの集合を返します。

select * from json_object_keys('{"f1":"abc","f2":{"f3":"a", "f4":"b"}}')

 json_object_keys
------------------
 f1
 f2

json_populate_record ( base anyelement, from_json json ) → anyelement

jsonb_populate_record ( base anyelement, from_json jsonb ) → anyelement

トップレベルのJSONオブジェクトをbase引数である複合型を持つ行に展開します。 JSONオブジェクトは出力行型の列名と一致するフィールドが検査されます。 (出力列名と関連のないフィールドは無視されます。) 典型的な使い方としては、baseの値が単にNULLで、これはオブジェクトフィールドと一致しない出力列にはNULLがセットされることを意味します。 しかし、baseNULLでないなら、それが持つ値が一致しない列に使われます。

JSON値を出力列のSQL型に変換する際に以下のルールが順に適用されます。

  • すべての場合にJSONのNULL値はSQLのNULLに変換されます。

  • 出力列がjson型あるいはjsonb型なら、JSON値は単にそのまま複製されます。

  • 出力行が複合(行)型でJSON値がJSONオブジェクトなら、これらのルールを再帰的に適用することによって、オブジェクトのフィールドが出力行型の列に変換されます。

  • 同様に、出力行が配列型でJSON値がJSON配列なら、これらのルールを再帰的に適用することによって、JSON配列の要素が出力配列の要素に変換されます。

  • それ以外の場合で、JSON値が文字列なら、その文字列の内容が列のデータ型に対応する入力変換関数に送られます。

  • さもなければ、通常のJSON値のテキスト表現が列のデータ型に対応する入力変換関数に送られます。

これらの関数の例ではJSON定数を使用していますが、典型的な使用法はそのjsonまたはjsonb列をFROM句の別のテーブルから外側に参照することです。 FROM句でjson_populate_recordを書くのは良い練習になります。 すべての取り出された列を重複した関数呼び出しなしに利用できるからです。

create type subrowtype as (d int, e text); create type myrowtype as (a int, b text[], c subrowtype);

select * from json_populate_record(null::myrowtype, '{"a": 1, "b": ["2", "a b"], "c": {"d": 4, "e": "a b c"}, "x": "foo"}')

 a |   b       |      c
---+-----------+-------------
 1 | {2,"a b"} | (4,"a b c")

jsonb_populate_record_valid ( base anyelement, from_json json ) → boolean

jsonb_populate_recordをテストする関数。 与えられた入力JSONオブジェクトに対してjsonb_populate_recordがエラーなしで終了する場合、すなわち有効な入力ならtrueを、そうでない場合はfalseを返します。

create type jsb_char2 as (a char(2));

select jsonb_populate_record_valid(NULL::jsb_char2, '{"a": "aaa"}');

 jsonb_populate_record_valid
-----------------------------
 f
(1 row)

select * from jsonb_populate_record(NULL::jsb_char2, '{"a": "aaa"}') q;

ERROR:  value too long for type character(2)

select jsonb_populate_record_valid(NULL::jsb_char2, '{"a": "aa"}');

 jsonb_populate_record_valid
-----------------------------
 t
(1 row)

select * from jsonb_populate_record(NULL::jsb_char2, '{"a": "aa"}') q;

 a
----
 aa
(1 row)

json_populate_recordset ( base anyelement, from_json json ) → setof anyelement

jsonb_populate_recordset ( base anyelement, from_json jsonb ) → setof anyelement

トップレベルのJSONオブジェクトをbase引数である複合型を持つ行の集合に展開します。 JSON配列の個々の要素は上のjson[b]_populate_recordで説明したように処理されます。

create type twoints as (a int, b int);

select * from json_populate_recordset(null::twoints, '[{"a":1,"b":2}, {"a":3,"b":4}]')

 a | b
---+---
 1 | 2
 3 | 4

json_to_record ( json ) → record

jsonb_to_record ( jsonb ) → record

トップレベルのJSONオブジェクトをAS句で定義した複合型を持つ行に展開します。 (recordを返すすべての関数では、呼び出す問い合わせは明示的にAS句でレコードの構造を定義しなければなりません。) 上のjson[b]_populate_recordで説明した方法で、出力レコードはJSONオブジェクトのフィールドで満たされます。 入力レコード値がないので、一致しない列は常にNULLで満たされます。

create type myrowtype as (a int, b text);

select * from json_to_record('{"a":1,"b":[1,2,3],"c":[1,2,3],"e":"bar","r": {"a": 123, "b": "a b c"}}') as x(a int, b text, c int[], d text, r myrowtype)

 a |    b    |    c    | d |       r
---+---------+---------+---+---------------
 1 | [1,2,3] | {1,2,3} |   | (123,"a b c")

json_to_recordset ( json ) → setof record

jsonb_to_recordset ( jsonb ) → setof record

トップレベルのJSON配列をAS句で定義した複合型を持つ行に展開します。 (recordを返すすべての関数では、呼び出す問い合わせは明示的にAS句でレコードの構造を定義しなければなりません。) 上のjson[b]_populate_recordで説明した方法で、JSON配列の要素は処理されます。

select * from json_to_recordset('[{"a":1,"b":"foo"}, {"a":"2","c":"bar"}]') as x(a int, b text)

 a |  b
---+-----
 1 | foo
 2 |

jsonb_set ( target jsonb, path text[], new_value jsonb [, create_if_missing boolean ] ) → jsonb

pathで指定された要素をnew_valueで置き換えてtargetを返します。 create_if_missingが真なら(デフォルトです)、pathで指定された項目が無い時にnew_valueが追加されます。 パス中のすべての初期のステップは存在しなければならず、さもなければtargetは変わらないままに返却されます。 パスの位置についての演算子については、pathの中にある負の整数はJSON配列の終わりから数えます。 パスの最後のステップが範囲外の配列のインデックスで、create_if_missingが真のときは、インデックスが負なら配列の最初に、正なら配列の最後に新しい値が追加されます。

jsonb_set('[{"f1":1,"f2":null},2,null,3]', '{0,f1}', '[2,3,4]', false)[{"f1": [2, 3, 4], "f2": null}, 2, null, 3]

jsonb_set('[{"f1":1,"f2":null},2]', '{0,f3}', '[2,3,4]')[{"f1": 1, "f2": null, "f3": [2, 3, 4]}, 2]

jsonb_set_lax ( target jsonb, path text[], new_value jsonb [, create_if_missing boolean [, null_value_treatment text ]] ) → jsonb

new_valueNULLでないなら、jsonb_setと同じ振る舞いをします。 そうでなければnull_value_treatmentにしたがいます。 null_value_treatmentは、'raise_exception''use_json_null''delete_key''return_target'のいずれかでなければなりません。 デフォルトは'use_json_null'です。

jsonb_set_lax('[{"f1":1,"f2":null},2,null,3]', '{0,f1}', null)[{"f1": null, "f2": null}, 2, null, 3]

jsonb_set_lax('[{"f1":99,"f2":null},2]', '{0,f3}', null, true, 'return_target')[{"f1": 99, "f2": null}, 2]

jsonb_insert ( target jsonb, path text[], new_value jsonb [, insert_after boolean ] ) → jsonb

new_valueを挿入してtargetを返します。 pathで指定した項目が配列要素で、insert_afterが偽(デフォルトです)ならばnew_valueはその項目の前に挿入され、insert_afterが真であれば後に挿入されます。 pathで指定した項目がオブジェクトフィールドならば、オブジェクトがすでにそのキーを含んでいない場合にのみnew_valueが挿入されます。 パス中のすべての初期のステップは存在しなければならず、さもなければtargetは変わらないままに返却されます。 pathについての演算子について言うと、path内の負の整数はJSON配列の終わりから数えます。 パスの最後のステップが範囲外の配列のインデックスで、インデックスが負なら配列の最初に、正なら配列の最後に新しい値が追加されます。

jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '"new_value"'){"a": [0, "new_value", 1, 2]}

jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '"new_value"', true){"a": [0, 1, "new_value", 2]}

json_strip_nulls ( json ) → json

jsonb_strip_nulls ( jsonb ) → jsonb

与えられたJSON値からNULLを持つオブジェクトフィールドをすべて削除します。 オブジェクトフィールドではないNULL値は変わりません。

json_strip_nulls('[{"f1":1, "f2":null}, 2, null, 3]')[{"f1":1},2,null,3]

jsonb_path_exists ( target jsonb, path jsonpath [, vars jsonb [, silent boolean ]] ) → boolean

JSONパスが指定したJSON値に対して項目を返すかどうかをチェックします。 (これは、述語チェック式ではなく、標準SQLのJSONパス式でのみ有用です。 なぜなら、それらは常に値を返すからです。) varsが指定されるなら、それはJSONオブジェクトでなければならず、そのフィールドはjsonpath式に置き換えられる名前を持つ値を提供します。 silent引数が指定されていてtrueなら、この関数は@?@@演算子が生成するのと同じエラーを抑止します。

jsonb_path_exists('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2, "max":4}')t

jsonb_path_match ( target jsonb, path jsonpath [, vars jsonb [, silent boolean ]] ) → boolean

指定したJSON値のJSONパス述語チェックの結果を返します。 (これは、パス結果が単一のブール値でない場合、失敗するかNULLを返すため、標準SQLのJSONパス述語ではなく、述語チェック式でのみ有用です)。 オプションのvarssilent引数は、jsonb_path_existsと同じように動作します。

jsonb_path_match('{"a":[1,2,3,4,5]}', 'exists($.a[*] ? (@ >= $min && @ <= $max))', '{"min":2, "max":4}')t

jsonb_path_query ( target jsonb, path jsonpath [, vars jsonb [, silent boolean ]] ) → setof jsonb

指定されたJSON値のJSONパスによって戻されるすべてのJSON項目を戻します。 標準SQLのJSONパス式の場合、targetから選択されたJSON値を返します。 述語チェック式の場合、述語チェックの結果を返します。 結果はtruefalsenullのいずれかです。 オプションのvarssilent引数はjsonb_path_existsと同じように動作します。

select * from jsonb_path_query('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2, "max":4}')

 jsonb_path_query
------------------
 2
 3
 4

jsonb_path_query_array ( target jsonb, path jsonpath [, vars jsonb [, silent boolean ]] ) → jsonb

指定されたJSON値のJSONパスによって返されるすべてのJSON項目を、JSON配列として返します。 パラメータはjsonb_path_queryと同じです。

jsonb_path_query_array('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2, "max":4}')[2, 3, 4]

jsonb_path_query_first ( target jsonb, path jsonpath [, vars jsonb [, silent boolean ]] ) → jsonb

指定されたJSON値のJSONパスによって返される最初のJSON項目を返します。 結果がない場合はNULLです。 パラメータはjsonb_path_queryと同じです。

jsonb_path_query_first('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2, "max":4}')2

jsonb_path_exists_tz ( target jsonb, path jsonpath [, vars jsonb [, silent boolean ]] ) → boolean

jsonb_path_match_tz ( target jsonb, path jsonpath [, vars jsonb [, silent boolean ]] ) → boolean

jsonb_path_query_tz ( target jsonb, path jsonpath [, vars jsonb [, silent boolean ]] ) → setof jsonb

jsonb_path_query_array_tz ( target jsonb, path jsonpath [, vars jsonb [, silent boolean ]] ) → jsonb

jsonb_path_query_first_tz ( target jsonb, path jsonpath [, vars jsonb [, silent boolean ]] ) → jsonb

これらの関数は、時間帯を考慮する日時値の比較をサポートすることを除いて、上で述べた、_tz接尾を除いた片割れの関数のように動作します。 以下の例では日付のみの値2015-08-02を時間帯付きタイムスタンプとして解釈することが必要で、結果はTimeZone設定に依存します。 この依存性のために、これらの関数は安定(stable)、として印付けされており、インデックスにはこれらの関数は使えないことを意味します。 これらの関数の片割れは不変(immutable)なので、インデックスで使えます。しかし、そうした比較を要求されるとエラーを吐きます。

jsonb_path_exists_tz('["2015-08-01 12:00:00-05"]', '$[*] ? (@.datetime() < "2015-08-02".datetime())')t

jsonb_pretty ( jsonb ) → text

与えられたJSON値を整形されたインデント付きテキストに変換します。

jsonb_pretty('[{"f1":1,"f2":null}, 2]')

[
    {
        "f1": 1,
        "f2": null
    },
    2
]

json_typeof ( json ) → text

jsonb_typeof ( jsonb ) → text

トップレベルのJSON値の型をテキスト文字列として返します。 可能な型は次のとおりです。 objectarraystringnumberbooleannull。 (nullの結果をSQLのNULLと混同してはいけません。以下の例をご覧ください。)

json_typeof('-123.4')number

json_typeof('null'::json)null

json_typeof(NULL::json) IS NULLt


9.16.2. SQL/JSONパス言語 #

SQL/JSONパス式は、XMLコンテンツへのアクセスで使用されるXPath式同様、JSON値から取り出す項目を指定します。 PostgreSQLではパス式はjsonpathデータ型として実装されており、8.14.7で説明されているすべての要素を使うことができます。

JSON問い合わせ関数と演算子は与えられたパス式をpath engineに渡して評価します。 式が問い合わせ対象のJSONデータにマッチすれば、関連するSQL/JSON項目が返却されます。 一致しない場合、結果はNULLfalse、または関数によって異なるエラーになります。 パス式はSQL/JSONパス言語で書かれ、算術式と関数を含むことができます。

パス式はjsonpathデータ型で認められた一連の要素からなります。 パス式は通常左から右へと評価されますが、括弧を使って演算の順序を変更することができます。 評価が成功すれば、一連のJSON項目が生成され、評価結果が指定した計算を完了したJSON問い合わせ関数に戻されます。

問い合わせ対象(context item)のJSONデータを参照するには、パス式内で$値を使います。 パスの最初の要素は常に$でなければなりません。 複数のアクセサ演算子をその後に記述することもできます。 この後に、JSON構造のレベルを1つずつ下ってコンテキスト項目のサブ項目を取得するアクセサ演算子を1つ以上指定することができます。 各アクセサ演算子は、前の評価ステップの結果に作用し、各入力項目から0個、1個、または複数の出力項目を生成します。

たとえば、次のようなパースしたいGPSトラッカーからのJSONデータがあるとします。

SELECT '{
  "track": {
    "segments": [
      {
        "location":   [ 47.763, 13.4034 ],
        "start time": "2018-10-14 10:05:14",
        "HR": 73
      },
      {
        "location":   [ 47.706, 13.2635 ],
        "start time": "2018-10-14 10:39:21",
        "HR": 135
      }
    ]
  }
}' AS json \gset

(上記の例は、psqlにコピー&ペーストして、以下の例の設定を行うことができます。 そうすると、psql:'json'を適切に引用符付けされた文字列定数に展開し、JSON値を含めます。)

使用可能なトラックセグメントを取り出すには、.keyアクセサ演算子を使用して、周辺のJSONオブジェクトを下っていく必要があります。 例:

=> select jsonb_path_query(:'json', '$.track.segments');
                                                                         jsonb_path_query
-----------------------------------------------------------​-----------------------------------------------------------​---------------------------------------------
 [{"HR": 73, "location": [47.763, 13.4034], "start time": "2018-10-14 10:05:14"}, {"HR": 135, "location": [47.706, 13.2635], "start time": "2018-10-14 10:39:21"}]

配列の内容を取り出すには、典型的には[*]演算子を使います。 次の例は、使用可能なすべてのトラックセグメントの位置座標を返します。

=> select jsonb_path_query(:'json', '$.track.segments[*].location');
 jsonb_path_query
-------------------
 [47.763, 13.4034]
 [47.706, 13.2635]

ここでは、JSON入力値($)全体から始め、.trackアクセサが"track"オブジェクトキーに関連付けられたJSONオブジェクトを選択し、.segmentsアクセサがそのオブジェクト内の"segments"キーに関連付けられたJSON配列を選択し、[*]アクセサがその配列の各要素を(一連の項目を生成しながら)選択し、.locationアクセサがそれらのオブジェクトのそれぞれの中の"location"キーに関連付けられたJSON配列を選択しました。 この例では、それらのオブジェクトのそれぞれに"location"キーがありましたが、もしそうでなければ、.locationアクセッサは単にその入力項目に対して何の出力も生成しなかったでしょう。

最初のセグメントの座標だけを返すには、[]アクセサ演算子の中で対応する添え字を指定することができます。 JSON配列インデックスは0スタートであることに注意してください。

=> select jsonb_path_query(:'json', '$.track.segments[0].location');
 jsonb_path_query
-------------------
 [47.763, 13.4034]

各段階でのパス評価結果は9.16.2.3に列挙されている一つ以上のjsonpath演算子とメソッドで処理することができます。 各々のメソッド名の前にピリオドを付けなければなりません。 たとえば配列の大きさを得ることができます。

=> select jsonb_path_query(:'json', '$.track.segments.size()');
 jsonb_path_query
------------------
 2

パス式内のjsonpath演算子とメソッドを使用する他の例については以下の9.16.2.3を参照してください。

パスには、SQLのWHERE句のように働くフィルタ式を含めることもできます。 フィルタ式はクェスチョンマークで始まり、カッコ内に条件を記述します。

? (condition)

フィルタ式はそれを適用するパス評価段階の直後に指定しなければなりません。 この段階の結果は、指定した条件を満たす項目だけが含まれるようにフィルタされます。 SQL/JSONは3値論理を定義しており、条件はtruefalseunknownのどれかを生成します。 unknownは値はSQLのNULLと同じ役割を果たし、is unknown述語で評価できます。 その後の評価段階ではtrueを返すフィルタ式に対応する項目だけが使われます。

フィルタ式内で利用できる関数と演算子は表 9.51にリストされています。 フィルタ式内では、考慮する必要のある値は@変数で示します。(つまり以前のパスステップの結果の一つです。) コンポーネント項目を取得するためにアクセサ演算子を@の後に記述することができます。

たとえば130より高いすべての心拍数を取り出したいとします。 これを実現するには、次のようにします。

=> select jsonb_path_query(:'json', '$.track.segments[*].HR ? (@ > 130)');
 jsonb_path_query
------------------
 135

そうした値を持つセグメントの開始時刻を得たい場合は、開始時刻を選択する前に無関係のセグメントを取り除く必要があります。 そうすることにより前の段階にフィルタ式が適用されるので、その条件で適用されるパスは異なります。

=> select jsonb_path_query(:'json', '$.track.segments[*] ? (@.HR > 130)."start time"');
   jsonb_path_query
-----------------------
 "2018-10-14 10:39:21"

必要なら複数のフィルタ式を順に使用することができます。 次の例では、関連する座標と高い心拍数値を持つ位置を含むすべてのセグメントの開始時間を選択します。

=> select jsonb_path_query(:'json', '$.track.segments[*] ? (@.location[1] < 13.4) ? (@.HR > 130)."start time"');
   jsonb_path_query
-----------------------
 "2018-10-14 10:39:21"

異なる入れ子レベルに対してフィルタ式を適用することもできます。 次の例では、まず位置ですべてのセグメントをフィルタし、もしあれば高い心拍数値を返します。

=> select jsonb_path_query(:'json', '$.track.segments[*] ? (@.location[1] < 13.4).HR ? (@ > 130)');
 jsonb_path_query
------------------
 135

フィルタ式をネストして、フィルタ式を相互にネストすることもできます。 次の例では、トラックに高心拍数値のセグメントが含まれている場合はそのサイズを返し、それ以外の場合は空のシーケンスを返します。

=> select jsonb_path_query(:'json', '$.track ? (exists(@.segments[*] ? (@.HR > 130))).segments.size()');
 jsonb_path_query
------------------
 2

9.16.2.1. 標準SQLとの違い #

PostgreSQLのSQL/JSONパス言語の実装はSQL/JSON標準と次の点が異なります。

9.16.2.1.1. ブール述語チェック式 #

標準SQLの拡張として、PostgreSQLパス式はブール述語になりますが、標準SQLでは述語はフィルタ内でのみ許されます。 標準SQLのパス式は、問い合わせられたJSON値の関連する要素を返しますが、述語チェック式は述語の単一の3値結果truefalseunknownを返します。 たとえば、次の標準SQLフィルタ式を記述できます。

=> select jsonb_path_query(:'json', '$.track.segments ?(@[*].HR > 130)');
                                jsonb_path_query
-----------------------------------------------------------​----------------------
 {"HR": 135, "location": [47.706, 13.2635], "start time": "2018-10-14 10:39:21"}

類似述語チェック式は単にtrueを返し、一致が存在することを示します。

=> select jsonb_path_query(:'json', '$.track.segments[*].HR > 130');
 jsonb_path_query
------------------
 true

注記

述語チェック式は@@演算子(およびjsonb_path_match関数)で必要であり、@?演算子(またはjsonb_path_exists関数)では使用すべきではありません。

9.16.2.1.2. Regular Expression Interpretation #

9.16.2.4で述べるように、like_regexフィルタで使用される正規表現パターンの解釈には些細な違いがあります。

9.16.2.2. 厳密モードと非厳密モード #

JSONデータを問い合わせる際、パス式は実際のJSONデータ構造に一致しないかも知れません。 存在しないオブジェクトのメンバあるいは配列要素へのアクセスは構造上のエラーとして定義されています。 SQL/JSONパス式には構造上のエラーを扱うための2つのモードがあります。

  • 非厳密(lax)モード(デフォルト)— パスエンジンは指定したパスを問い合わせデータに暗黙的に適合させます。 以下に説明するように修正できない構造エラーは抑制され、一致は生成されません。

  • 厳密(strict)モード — 構造上のエラーがあるとエラーが発生します。

非厳密モードは、JSONデータが期待されるスキーマに沿わないときにJSON文書とパス式のマッチングを助けます。 あるオペランドが操作の要件に合わないときにはそれをSQL/JSON配列にまとめたり、あるいは操作を行う前にそれをSQL/JSONシーケンスに展開することもできます。 また非厳密モードにおいては、比較演算子は自動的にオペランドを展開し、SQL/JSON配列をそのまま比較することができます。 大きさ1の配列はその単独要素と同じものとして扱われます。 自動展開は以下の場合に行われません。

  • それぞれ配列の型、要素数を返すtype()size()をパス式が含む。

  • 問い合わせ対象のJSONデータが入れ子の配列を含む。 この場合はもっとも外側の配列のみが展開され、内側の配列は変わりません。 ですから、それぞれの評価段階において1レベルのみに暗黙的な展開が行われます。

たとえば、上述のGPSデータに問い合わせする場合、非厳密モードでは配列のセグメントを含んでいるという事実から抽出できます。

=> select jsonb_path_query(:'json', 'lax $.track.segments.location');
 jsonb_path_query
-------------------
 [47.763, 13.4034]
 [47.706, 13.2635]

厳密モードでは、指定されたパスは問い合わせ対象のJSONドキュメントの構造と正確に一致する必要があるため、このパス式を使用するとエラーが発生します。

=> select jsonb_path_query(:'json', 'strict $.track.segments.location');
ERROR:  jsonpath member accessor can only be applied to an object

非厳密モードと同じ結果を得るには、segments配列を明示的に展開する必要があります。

=> select jsonb_path_query(:'json', 'strict $.track.segments[*].location');
 jsonb_path_query
-------------------
 [47.763, 13.4034]
 [47.706, 13.2635]

非厳密モードの展開動作は、驚くべき結果をもたらす可能性があります。 たとえば、.**アクセサを使用する次の問い合わせは、すべてのHR値を2回選択します。

=> select jsonb_path_query(:'json', 'lax $.**.HR');
 jsonb_path_query
------------------
 73
 135
 73
 135

これは.**アクセサがsegmentsとその各々の要素の両方を検索するからです。 一方、.HRアクセサは非厳密モードでは自動的に配列を展開します。 予期しない結果を避けるには、.**アクセサを厳密モードでのみ使うことをお勧めします。 次の問い合わせはHRの各値を一度だけ検索します。

=> select jsonb_path_query(:'json', 'strict $.**.HR');
 jsonb_path_query
------------------
 73
 135

配列の展開は予期しない結果をもたらす可能性もあります。 location配列をすべて選択する次の例を考えてみましょう。

=> select jsonb_path_query(:'json', 'lax $.track.segments[*].location');
 jsonb_path_query
-------------------
 [47.763, 13.4034]
 [47.706, 13.2635]
(2 rows)

予想どおり、配列全体が返されます。 しかし、フィルタ式を適用すると、配列が展開され、各項目が評価されて、式に一致する項目のみが返されます。

=> select jsonb_path_query(:'json', 'lax $.track.segments[*].location ?(@[*] > 15)');
 jsonb_path_query
------------------
 47.763
 47.706
(2 rows)

これは、完全な配列がpath式によって選択されるという事実にもかかわらずです。 厳密モードを使用して、配列の選択を復元します。

=> select jsonb_path_query(:'json', 'strict $.track.segments[*].location ?(@[*] > 15)');
 jsonb_path_query
-------------------
 [47.763, 13.4034]
 [47.706, 13.2635]
(2 rows)

9.16.2.3. SQL/JSONパス演算子とメソッド #

表 9.50jsonpathで利用可能な演算子とメソッドを示します。 単項演算子とメソッドは以前のパスステップから生じた複数の値に適用できますが、二項演算子(加算など)は単一の値にしか適用できないことに注意してください。 非厳密モードでは、配列に適用されるメソッドは配列内の各値に対して実行されます。 例外は.type().size()で、配列自分自身に適用されます。

表9.50 jsonpath演算子とメソッド

演算子/メソッド

説明

number + numbernumber

加算

jsonb_path_query('[2]', '$[0] + 3')5

+ numbernumber

単項のプラス(演算なし)。加算と違って、複数の値に渡って適用できます。

jsonb_path_query_array('{"x": [2,3,4]}', '+ $.x')[2, 3, 4]

number - numbernumber

減算

jsonb_path_query('[2]', '7 - $[0]')5

- numbernumber

負符号。減算と違って、複数の値に渡って適用できます。

jsonb_path_query_array('{"x": [2,3,4]}', '- $.x')[-2, -3, -4]

number * numbernumber

乗算

jsonb_path_query('[4]', '2 * $[0]')8

number / numbernumber

除算

jsonb_path_query('[8.5]', '$[0] / 2')4.2500000000000000

number % numbernumber

剰余(残り)

jsonb_path_query('[32]', '$[0] % 10')2

value . type()string

JSON項目の型(json_typeofを参照)

jsonb_path_query_array('[1, "2", {}]', '$[*].type()')["number", "string", "object"]

value . size()number

JSON項目の大きさ(配列の要素数。配列でなければ1)

jsonb_path_query('{"m": [11, 15]}', '$.m.size()')2

value . boolean()boolean

JSONのブール値、数値、または文字列から変換されたブール値。

jsonb_path_query_array('[1, "yes", false]', '$[*].boolean()')[true, true, false]

value . string()string

JSONのブール値、数値、文字列、または日時から変換された文字列値。

jsonb_path_query_array('[1.23, "xyz", false]', '$[*].string()')["1.23", "xyz", "false"]

jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp().string()')"2023-08-15T12:34:56"

value . double()number

JSON数値あるいは文字列から変換した概算の浮動小数点数

jsonb_path_query('{"len": "1.9"}', '$.len.double() * 2')3.8

number . ceiling()number

引数より大きいか等しく、与えられた数に最も近い整数

jsonb_path_query('{"h": 1.3}', '$.h.ceiling()')2

number . floor()number

引数より小さいか等しく、与えられた数に最も近い整数

jsonb_path_query('{"h": 1.7}', '$.h.floor()')1

number . abs()number

与えられた数の絶対値

jsonb_path_query('{"z": -0.3}', '$.z.abs()')0.3

value . bigint()bigint

JSONの数値または文字列から変換された大きな整数値。

jsonb_path_query('{"len": "9876543219"}', '$.len.bigint()')9876543219

value . decimal( [ precision [ , scale ] ] )decimal

JSONの数値または文字列から変換された丸められた10進数値(精度および位取りは整数値である必要があります)。

jsonb_path_query('1234.5678', '$.decimal(6, 2)')1234.57

value . integer()integer

JSONの数値または文字列から変換された整数値。

jsonb_path_query('{"len": "12345"}', '$.len.integer()')12345

value . number()numeric

JSONの数値または文字列から変換されたNumeric値。

jsonb_path_query('{"len": "123.45"}', '$.len.number()')123.45

string . datetime()datetime_type (注記を参照)

文字列から変換した日時値

jsonb_path_query('["2015-8-1", "2015-08-12"]', '$[*] ? (@.datetime() < "2015-08-2".datetime())')"2015-8-1"

string . datetime(template)datetime_type (注記を参照)

指定のto_timestampテンプレートを使って文字列から変換した日時値

jsonb_path_query_array('["12:30", "18:40"]', '$[*].datetime("HH24:MI")')["12:30:00", "18:40:00"]

string . date()date

文字列から変換された日付値。

jsonb_path_query('"2023-08-15"', '$.date()')"2023-08-15"

string . time()time without time zone

文字列から変換した時間帯のない時刻値

jsonb_path_query('"12:34:56"', '$.time()')"12:34:56"

string . time(precision)time without time zone

文字列から変換された時間帯のない時間の値。分数の秒は指定された精度に調整されます。

jsonb_path_query('"12:34:56.789"', '$.time(2)')"12:34:56.79"

string . time_tz()time with time zone

文字列から変換されたタイムゾーン値を持つ時間。

jsonb_path_query('"12:34:56 +05:30"', '$.time_tz()')"12:34:56+05:30"

string . time_tz(precision)time with time zone

文字列から変換された時間帯を持つ時間。分数の秒は指定された精度に調整されます。

jsonb_path_query('"12:34:56.789 +05:30"', '$.time_tz(2)')"12:34:56.79+05:30"

string . timestamp()timestamp without time zone

文字列から変換された時間帯なしのタイムスタンプ

jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp()')"2023-08-15T12:34:56"

string . timestamp(precision)timestamp without time zone

文字列から変換された時間帯なしのタイムスタンプ値。分数の秒数は指定された精度に調整されます。

jsonb_path_query('"2023-08-15 12:34:56.789"', '$.timestamp(2)')"2023-08-15T12:34:56.79"

string . timestamp_tz()timestamp with time zone

文字列から変換された時間帯を持つタイムスタンプ。

jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.timestamp_tz()')"2023-08-15T12:34:56+05:30"

string . timestamp_tz(precision)timestamp with time zone

文字列から変換された時間帯を持つタイムスタンプ値。分数の秒数は指定された精度に調整されます。

jsonb_path_query('"2023-08-15 12:34:56.789 +05:30"', '$.timestamp_tz(2)')"2023-08-15T12:34:56.79+05:30"

object . keyvalue()array

以下の3つのフィールドを含むオブジェクトの配列で表現したオブジェクトのキー/値ペア。 "key""value""id""id"はキー/値ペアが属するオブジェクトのユニーク識別子です。

jsonb_path_query_array('{"x": "20", "y": 32}', '$.keyvalue()')[{"id": 0, "key": "x", "value": "20"}, {"id": 0, "key": "y", "value": 32}]


注記

datetime()datetime(template)の結果型はdatetimetztimetimestamptz、あるいはtimestampです。 両方のメソッドは結果型を動的に決定します。

datetime()メソッドは入力文字列をdatetimetztimetimestamptztimestampのISO形式に対して順にマッチを試みます。 最初にマッチした形式で停止し、関連するデータ型を出力します。

datetime(template)メソッドは与えられたテンプレート文字列にあるフィールドに従って結果型を決定します。

datetime()datetime(template)to_timestampSQL関数と同じ解析ルール(参照9.8)を用いますが、3つの例外があります。 一番目に、これらのメソッドは一致しないテンプレートパターンを許容しません。二番目に次の区切り文字のみを許容します。負符号、ピリオド、斜線(スラッシュ)、カンマ、アポストロフィー、セミコロン、コロン、空白、です。 三番目にテンプレート文字列中の区切り文字は正確に入力文字列と一致しなければなりません。

異なる日時型の比較が必要なら、暗黙的なキャストが適用されます。 date値はtimestampあるいはtimestamptzにキャストできます。 timestamptimestamptzに、timetimetzにキャストできます。 しかし、これらの変換は最初のものを除くすべてが現在のTimeZone設定に依存します。ですから時間帯を認識するjsonpath関数中でのみ実行可能です。 同様に、文字列を日付/時刻型に変換する他の日付/時刻関連のメソッドも、現在のTimeZone設定を含む可能性があるこのキャストを行います。 したがって、これらの変換は、timezoneを意識したjsonpath関数内でのみ実行できます。

表 9.51に利用可能なフィルタ式要素を示します。

表9.51 jsonpathフィルタ式要素

述語/値

説明

value == valueboolean

等値比較(これと他の比較演算子はすべてのJSONスカラ値で使えます)

jsonb_path_query_array('[1, "a", 1, 3]', '$[*] ? (@ == 1)')[1, 1]

jsonb_path_query_array('[1, "a", 1, 3]', '$[*] ? (@ == "a")')["a"]

value != valueboolean

value <> valueboolean

非等値比較

jsonb_path_query_array('[1, 2, 1, 3]', '$[*] ? (@ != 1)')[2, 3]

jsonb_path_query_array('["a", "b", "c"]', '$[*] ? (@ <> "b")')["a", "c"]

value < valueboolean

未満比較

jsonb_path_query_array('[1, 2, 3]', '$[*] ? (@ < 2)')[1]

value <= valueboolean

以下比較

jsonb_path_query_array('["a", "b", "c"]', '$[*] ? (@ <= "b")')["a", "b"]

value > valueboolean

より大きい比較

jsonb_path_query_array('[1, 2, 3]', '$[*] ? (@ > 2)')[3]

value >= valueboolean

以上比較

jsonb_path_query_array('[1, 2, 3]', '$[*] ? (@ >= 2)')[2, 3]

trueboolean

JSON定数

jsonb_path_query('[{"name": "John", "parent": false}, {"name": "Chris", "parent": true}]', '$[*] ? (@.parent == true)'){"name": "Chris", "parent": true}

falseboolean

JSON定数

jsonb_path_query('[{"name": "John", "parent": false}, {"name": "Chris", "parent": true}]', '$[*] ? (@.parent == false)'){"name": "John", "parent": false}

nullvalue

JSON定数null(SQLとは違ってnullとの比較は通常通り動作することに注意してください。)

jsonb_path_query('[{"name": "Mary", "job": null}, {"name": "Michael", "job": "driver"}]', '$[*] ? (@.job == null) .name')"Mary"

boolean && booleanboolean

論理AND

jsonb_path_query('[1, 3, 7]', '$[*] ? (@ > 1 && @ < 5)')3

boolean || booleanboolean

論理OR

jsonb_path_query('[1, 3, 7]', '$[*] ? (@ < 1 || @ > 5)')7

! booleanboolean

論理NOT

jsonb_path_query('[1, 3, 7]', '$[*] ? (!(@ < 5))')7

boolean is unknownboolean

論理条件がunknownであるかどうかを検査します。

jsonb_path_query('[-1, 2, 7, "foo"]', '$[*] ? ((@ > 0) is unknown)')"foo"

string like_regex string [ flag string ] → boolean

最初のオペランドが2番目のオペランドで与えられる正規表現にマッチするかどうか検査します。 オプションでflag文字列で記述される変更を伴います。(9.16.2.4を参照してください。)

jsonb_path_query_array('["abc", "abd", "aBdC", "abdacb", "babc"]', '$[*] ? (@ like_regex "^ab.*c")')["abc", "abdacb"]

jsonb_path_query_array('["abc", "abd", "aBdC", "abdacb", "babc"]', '$[*] ? (@ like_regex "^ab.*c" flag "i")')["abc", "aBdC", "abdacb"]

string starts with stringboolean

2番目の文字列が1番目のオペランドの最初の部分文字列かどうかを検査します。

jsonb_path_query('["John Smith", "Mary Stone", "Bob Johnson"]', '$[*] ? (@ starts with "John")')"John Smith"

exists ( path_expression )boolean

パス式が少なくとも一つのSQL/JSON項目とマッチするかどうかを検査します。 パス式がエラーとなる場合はunknownを返します。2番目の例は厳密モードでキーが存在しないエラーを回避するためにこれを使っています。

jsonb_path_query('{"x": [1, 2], "y": [2, 4]}', 'strict $.* ? (exists (@ ? (@[*] > 2)))')[2, 4]

jsonb_path_query_array('{"value": 41}', 'strict $ ? (exists (@.name)) .name')[]


9.16.2.4. SQL/JSON正規表現 #

SQL/JSONパス式ではlike_regexフィルタを使ってテキストを正規表現にマッチさせることができます。 たとえば、次のSQL/JSONパス式問い合わせは、英語の母音で始まる配列内のすべての文字列に大文字小文字を無視してマッチするでしょう。

$[*] ? (@ like_regex "^[aeiou]" flag "i")

オプションのflag文字列は一つ以上の文字を含むことができます。 iは大文字小文字を無視したマッチ、m^$で改行にマッチ、s.が改行にマッチ、qはパターン全体を参照します。(振る舞いを単純な部分文字列マッチとします)

SQL/JSON標準は正規表現の定義を、XQuery標準を使用するLIKE_REGEX演算子から借りています。 PostgreSQLは今の所LIKE_REGEX演算子をサポートしていません。 ですから、like_regexフィルタは9.7.3で説明されているPOSIX正規表現で実装されています。 このことにより、9.7.3.8で列挙されているSQL/JSON標準の振る舞いとの小さな違いが生じます。 しかし、ここで述べているフラグ文字の非互換性はSQL/JSONには適用されないことに注意してください。SQL/JSONは、XQueryのフラグ文字をPOSIXエンジンが期待するのと一致するように解釈するからです。

like_regexのパターン引数は8.14.7で説明されているルールにしたがって書かれたJSONパス文字列リテラルであることに注意してください。 これは、正規表現で使用するすべてのバックスラッシュを二重に書かなければならないことを意味します。 たとえば、数字のみを含むroot文書の文字列値にマッチさせるには以下のようにします。

$.* ? (@ like_regex "^\\d+$")

9.16.3. SQL/JSON問い合わせ関数 #

表 9.52で記述されたSQL/JSON関数JSON_EXISTS()JSON_QUERY()JSON_VALUE()は、JSON文書への問い合わせに使用できます。 これらの各関数は、path_expression(SQL/JSONパス問い合わせ)をcontext_item(文書)に適用します。 path_expressionの内容の詳細については、9.16.2を参照してください。 path_expressionはリファレンス変数にすることもできます。その値は、各関数でサポートされているPASSING句でそれぞれの名前で指定されます。 context_itemには、jsonbの値、または文字の並びにキャストできるjsonbを指定できます。

表9.52 SQL/JSON問い合わせ関数

関数の呼び出し形式

説明

JSON_EXISTS (
context_item, path_expression
[ PASSING { value AS varname } [, ...]]
[{ TRUE | FALSE | UNKNOWN | ERROR } ON ERROR ]) → boolean

  • context_itemに適用されたSQL/JSON path_expressionが項目を生成する場合は真を返し、それ以外の場合は偽を返します。

  • ON ERROR句は、path_expressionの評価中にエラーが発生した場合の動作を指定します。 ERRORを指定すると、適切なメッセージとともにエラーを引き起こします。 他のオプションにはboolean値であるFALSEまたはTRUE、あるいは実際にはSQL NULLであるUNKNOWNの値を返すものがあります。 ON ERROR句が指定されていない場合のデフォルトでは、boolean値のFALSEを返します。

例:

JSON_EXISTS(jsonb '{"key1": [1,2,3]}', 'strict $.key1[*] ? (@ > $x)' PASSING 2 AS x)t

JSON_EXISTS(jsonb '{"a": [1,2,3]}', 'lax $.a[5]' ERROR ON ERROR)f

JSON_EXISTS(jsonb '{"a": [1,2,3]}', 'strict $.a[5]' ERROR ON ERROR)

ERROR:  jsonpath array subscript is out of bounds

JSON_QUERY (
context_item, path_expression
[ PASSING { value AS varname } [, ...]]
[ RETURNING data_type [ FORMAT JSON [ ENCODING UTF8 ] ] ]
[ { WITHOUT | WITH { CONDITIONAL | [UNCONDITIONAL] } } [ ARRAY ] WRAPPER ]
[ { KEEP | OMIT } QUOTES [ ON SCALAR STRING ] ]
[ { ERROR | NULL | EMPTY { [ ARRAY ] | OBJECT } | DEFAULT expression } ON EMPTY ]
[ { ERROR | NULL | EMPTY { [ ARRAY ] | OBJECT } | DEFAULT expression } ON ERROR ]) → jsonb

  • SQL/JSONpath_expressioncontext_itemに適用した結果を返します。

  • デフォルトでは、結果はjsonb型の値として返されますが、RETURNING句を使って、結果が正常に強制される他の型を返すことができます。

  • パス式が複数の結果を返す場合、それらの値を適切なJSON文字列にするために、WITH WRAPPER句を使用してこれらの値をラップする必要があります。 なぜなら、デフォルトの動作は、WITHOUT WRAPPERが指定されているかのようにラップしないからです。 WITH WRAPPER句は、デフォルトではWITH UNCONDITIONAL WRAPPERを意味すると解釈されます。これは、単一の結果値であってもラップされることを意味します。 複数の値が存在する場合にのみラッパーを適用するには、WITH CONDITIONAL WRAPPERを指定します。 WITHOUT WRAPPERが指定されていて、結果に複数の値が含まれると、エラーとして扱われます。

  • 結果がスカラ文字列の場合、デフォルトでは戻り値は引用符で囲まれ、有効なJSON値になります。 これは、KEEP QUOTESを指定することで明示的にできます。 逆に、OMIT QUOTESを指定することで引用符を省略できます。 結果が有効なJSON値である保証には、WITH WRAPPERも指定されている場合、OMIT QUOTESは指定できません。

  • ON EMPTY句は、path_expressionを評価した結果空の集合が生成される場合の動作を指定します。 ON ERROR句は、path_expressionを評価した際、結果値をRETURNING型に強制した際、またはpath_expression評価で空の集合が返されON EMPTY式を評価した際にエラーが発生する場合の動作を指定します。

  • ON EMPTYON ERRORの両方で、ERRORを指定すると、適切なエラーとともにメッセージがスローされます。 他のオプションにはSQL NULL、空の配列(EMPTY [ARRAY])、空のオブジェクト(EMPTY OBJECT)、jsonbまたはRETURNINGで指定されたタイプに強制できるユーザ指定の式(DEFAULT expression)があります。 ON EMPTYあるいはON ERROR句が指定されていない場合のデフォルトでは、SQL NULL値を返します。

例:

JSON_QUERY(jsonb '[1,[2,3],null]', 'lax $[*][$off]' PASSING 1 AS off WITH CONDITIONAL WRAPPER)3

JSON_QUERY(jsonb '{"a": "[1, 2]"}', 'lax $.a' OMIT QUOTES)[1, 2]

JSON_QUERY(jsonb '{"a": "[1, 2]"}', 'lax $.a' RETURNING int[] OMIT QUOTES ERROR ON ERROR)

ERROR:  malformed array literal: "[1, 2]"
DETAIL:  Missing "]" after array dimensions.

JSON_VALUE (
context_item, path_expression
[ PASSING { value AS varname } [, ...]]
[ RETURNING data_type ]
[ { ERROR | NULL | DEFAULT expression } ON EMPTY ]
[ { ERROR | NULL | DEFAULT expression } ON ERROR ]) → text

  • SQL/JSON path_expressioncontext_itemに適用した結果を返します。

  • JSON_VALUE()を使用するのは、抽出された値が単一のSQL/JSONスカラ項目であると予想される場合のみです。複数の値の取得はエラーとして扱われます。 抽出された値がオブジェクトまたは配列であると予想される場合は、代わりにJSON_QUERY関数を使用します。

  • デフォルトでは、結果は単一のスカラ値である必要があり、text型の値として返されます。 ただし、RETURNING句は、結果が正常に強制できる他の型として使用できます。

  • ON ERROR句とON EMPTY句のセマンティクスは、JSON_QUERYの説明で説明したものと似ていますが、エラーを発生する代わりに返される値の集合が異なります。

  • JSON_VALUEによって返されるスカラ文字列は、JSON_QUERYOMIT QUOTESを指定するのと同じように、常に引用符が削除されることに注意してください。

例:

JSON_VALUE(jsonb '"123.45"', '$' RETURNING float)123.45

JSON_VALUE(jsonb '"03:04 2015-02-01"', '$.datetime("HH24:MI YYYY-MM-DD")' RETURNING date)2015-02-01

JSON_VALUE(jsonb '[1,2]', 'strict $[$off]' PASSING 1 as off)2

JSON_VALUE(jsonb '[1,2]', 'strict $[*]' DEFAULT 9 ON ERROR)9


注記

context_item式は、まだjsonb型でない場合、暗黙キャストによってjsonbに変換されます。 ただし、その変換中に発生する解析エラーは、無条件に発生します。つまり、(指定または暗黙的な)ON ERROR句に従って処理されません。

注記

path_expressionがSQLnullを返す場合、JSON_VALUE()はSQL NULLを返します。一方、JSON_QUERY()はJSON nullをそのまま返します。

9.16.4. JSON_TABLE #

JSON_TABLEJSONデータを問い合わせ、結果を通常のSQLテーブルとしてアクセスできるリレーショナルビューとして表示するSQL/JSON関数です。 JSON_TABLEは、SELECTUPDATE、またはDELETEFROM句内で使用できます。また、MERGE文のデータソースとしても使用できます。

JSONデータを入力として、JSON_TABLEはJSONパス式を使用して、提供されたデータの一部を抽出し、構築されたビューの行パターンとして使用します。 行パターンで指定された各SQL/JSON値は、構築されたビューの別々の行のソースとして機能します。

行パターンを列に分割するために、JSON_TABLEは作成されたビューのスキーマを定義するCOLUMNS句を提供します。 各列に対して、個別のJSONパス式を指定して、行パターンに対して評価されるようにできます。これは、指定された出力行の特定の列の値になります。

行パターンのネストされたレベルに格納されたJSONデータは、NESTED PATH句を使用して抽出できます。 各NESTED PATH句は、行パターンのネストされたレベルからのデータを使用して1つ以上の列を生成するために使用できます。 これらの列は、最上位のCOLUMNS句と同様のCOLUMNS句を使用して指定できます。 NESTED COLUMNSから構成される行は子行child rows)と呼ばれ、親のCOLUMNS句で指定された列から構成される行に対して結合され、最終的なビューの行が得られます。 子列自体はNESTED PATH指定を含むことができ、任意のネストレベルにあるデータを抽出することができます。 同じレベルにある複数のNESTED PATHによって生成された列は、互いに兄弟siblings)と見なされ、親行と結合された後の行はUNIONを使用して結合されます。

JSON_TABLEが生成する行は、それを生成した行に横方向に結合されるため、JSONデータを保持する元のテーブルに構築されたビューを明示的に結合する必要はありません。

構文は次のとおりです。

JSON_TABLE (
    context_item, path_expression [ AS json_path_name ] [ PASSING { value AS varname } [, ...] ]
    COLUMNS ( json_table_column [, ...] )
    [ { ERROR | EMPTY [ARRAY]} ON ERROR ]
)



ここでjson_table_columnは次のとおりです。

  name FOR ORDINALITY
  | name type
        [ FORMAT JSON [ENCODING UTF8]]
        [ PATH path_expression ]
        [ { WITHOUT | WITH { CONDITIONAL | [UNCONDITIONAL] } } [ ARRAY ] WRAPPER ]
        [ { KEEP | OMIT } QUOTES [ ON SCALAR STRING ] ]
        [ { ERROR | NULL | EMPTY { [ARRAY] | OBJECT } | DEFAULT expression } ON EMPTY ]
        [ { ERROR | NULL | EMPTY { [ARRAY] | OBJECT } | DEFAULT expression } ON ERROR ]
  | name type EXISTS [ PATH path_expression ]
        [ { ERROR | TRUE | FALSE | UNKNOWN } ON ERROR ]
  | NESTED [ PATH ] path_expression [ AS json_path_name ] COLUMNS ( json_table_column [, ...] )

各構文要素について、以下でさらに詳しく説明します。

context_item, path_expression [ AS json_path_name ] [ PASSING { value AS varname } [, ...]]

context_itemは問い合わせの入力ドキュメントを指定し、path_expressionは問い合わせを定義するSQL/JSONパス式であり、json_path_namepath_expressionのオプションの名前です。 オプションのPASSING句は、path_expressionで言及されている変数にデータ値を提供します。 前述の要素を使用して入力データを評価した結果はrow patternと呼ばれ、構築されたビューの行値のソースとして使用されます。

COLUMNS ( json_table_column [, ...] )

構築されたビューのスキーマを定義するCOLUMNS句。 この句では、各列に対して、行パターンに対してJSONパス式を適用することによって得られるSQL/JSON値を指定できます。 json_table_columnには、次の種類があります。

name FOR ORDINALITY

1から始まる連続した行番号を提供する序数列を追加します。 各NESTED PATH(下記参照)は、ネストされた序数列に対してそれぞれ独自のカウンタを持ちます。

name type [FORMAT JSON [ENCODING UTF8]] [ PATH path_expression ]

指定されたtypeに強制変換した後、ビューの出力行にpath_expressionを適用して得られたSQL/JSON値を挿入します。

FORMAT JSONを指定すると、値が有効なjsonオブジェクトであることが明示的に指定されます。 FORMAT JSONを指定するのは、typebpcharbyteacharacter varyingnamejsonjsonbtext、またはこれらの型のドメインのいずれかである場合に限られます。

オプションで、WRAPPERQUOTES句を指定して出力をフォーマットすることもできます。 引用符なしのリテラルは有効なjson値を構成しないため、QUOTESを指定すると、FORMAT JSONが上書きされることに注意してください。

オプションで、ON EMPTYON ERROR句を使用して、JSONパス評価の結果が空の場合と、JSONパスの評価中あるいはSQL/JSON値を指定された型に強制変換したときにエラーが発生した場合に対して、エラーを発生するか、指定された値を返すかをそれぞれ指定できます。 どちらもデフォルトはNULLです。

注記

この句は内部的にJSON_VALUEまたはJSON_QUERYと同じ意味になります。 後者は、指定された型がスカラ型でない場合、またはFORMAT JSONWRAPPER、またはQUOTES句のいずれかが存在する場合です。

name type EXISTS [ PATH path_expression ]

指定されたtypeに強制変換した後、ビューの出力行にpath_expressionを適用して得られたブール値を挿入します。

この値は、PATH式を行パターンに適用した結果、値が生成されるかどうかに対応します。

指定されたtypeboolean型からのキャストを持つべきです。

オプションでON ERRORを使用して、JSONパス評価中にエラーが発生した場合、またはSQL/JSON値を指定された型に強制変換した場合に、エラーを発生するか、指定された値を返すかを指定できます。 デフォルトは、ブール値FALSEを返します。

注記

この句は内部的にはJSON_EXISTSと同じ意味に変換されます。

NESTED [ PATH ] path_expression [ AS json_path_name ] COLUMNS ( json_table_column [, ...] )

行パターンのネストされたレベルからSQL/JSON値を抽出し、COLUMNS副句で定義された1つ以上の列を生成し、それらの列に抽出されたSQL/JSON値を挿入します。 COLUMNS副句のjson_table_column式は、親のCOLUMNS句と同じ構文を使用します。

NESTED PATH構文は再帰的です。 したがって、複数のNESTED PATH副構文を互いに指定することで、複数のネストされたレベルを下に移動できます。 これにより、SQL文内で複数のJSON_TABLE式を連鎖させるのではなく、単一の関数呼び出しでJSONオブジェクトと配列の階層をネスト解除できます。

注記

上記のjson_table_columnの各種類において、PATH句が省略された場合、パス式$.nameが使用されます。 ここで、nameは指定された列名です。

AS json_path_name

オプションのjson_path_nameは、指定されたpath_expressionの識別子として機能します。 名前は一意でなければならず、列名と区別する必要があります。

{ ERROR | EMPTY } ON ERROR

オプションのON ERRORは、最上位のpath_expressionを評価する際のエラー処理方法を指定するために使用できます。 エラーを発生する場合はERRORを使用し、空のテーブル、つまり0行を含むテーブルを返す場合はEMPTYを使用します。 この句は、列の評価時に発生するエラーには影響しないことに注意してください。 この場合の動作は、ON ERROR句が指定された列に対して指定されているかどうかによって異なります。

Examples

以下の例では、次の表にJSONデータを含めます。

CREATE TABLE my_films ( js jsonb );

INSERT INTO my_films VALUES (
'{ "favorites" : [
   { "kind" : "comedy", "films" : [
     { "title" : "Bananas",
       "director" : "Woody Allen"},
     { "title" : "The Dinner Game",
       "director" : "Francis Veber" } ] },
   { "kind" : "horror", "films" : [
     { "title" : "Psycho",
       "director" : "Alfred Hitchcock" } ] },
   { "kind" : "thriller", "films" : [
     { "title" : "Vertigo",
       "director" : "Alfred Hitchcock" } ] },
   { "kind" : "drama", "films" : [
     { "title" : "Yojimbo",
       "director" : "Akira Kurosawa" } ] }
  ] }');

次の問い合わせは、JSON_TABLEを使用して、my_filmsテーブル内のJSONオブジェクトを、通常の列を伴って元のJSONに含まれるキーkindtitle、およびdirectorの列を含むビューに変換する方法を示しています。

SELECT jt.* FROM
 my_films,
 JSON_TABLE (js, '$.favorites[*]' COLUMNS (
   id FOR ORDINALITY,
   kind text PATH '$.kind',
   title text PATH '$.films[*].title' WITH WRAPPER,
   director text PATH '$.films[*].director' WITH WRAPPER)) AS jt;

 id |   kind   |             title              |             director
----+----------+--------------------------------+----------------------------------
  1 | comedy   | ["Bananas", "The Dinner Game"] | ["Woody Allen", "Francis Veber"]
  2 | horror   | ["Psycho"]                     | ["Alfred Hitchcock"]
  3 | thriller | ["Vertigo"]                    | ["Alfred Hitchcock"]
  4 | drama    | ["Yojimbo"]                    | ["Akira Kurosawa"]
(4 rows)

上記の問い合わせを次のように変更すると、トップレベルのJSONパス式で指定されたフィルタでPASSING引数の使用方法と、個々の列に対するさまざまなオプションが表示されます。

SELECT jt.* FROM
 my_films,
 JSON_TABLE (js, '$.favorites[*] ? (@.films[*].director == $filter)'
   PASSING 'Alfred Hitchcock' AS filter, 'Vertigo' AS filter2
     COLUMNS (
     id FOR ORDINALITY,
     kind text PATH '$.kind',
     title text FORMAT JSON PATH '$.films[*].title' OMIT QUOTES,
     director text PATH '$.films[*].director' KEEP QUOTES)) AS jt;

 id |   kind   |  title  |      director
----+----------+---------+--------------------
  1 | horror   | Psycho  | "Alfred Hitchcock"
  2 | thriller | Vertigo | "Alfred Hitchcock"
(2 rows)

以下は、タイトルとディレクターの列を生成するためにNESTED PATHを使用する上記の問い合わせの修正版で、親の列idとkindにどのように結合されるかを示しています。

SELECT jt.* FROM
 my_films,
 JSON_TABLE ( js, '$.favorites[*] ? (@.films[*].director == $filter)'
   PASSING 'Alfred Hitchcock' AS filter
   COLUMNS (
    id FOR ORDINALITY,
    kind text PATH '$.kind',
    NESTED PATH '$.films[*]' COLUMNS (
      title text FORMAT JSON PATH '$.title' OMIT QUOTES,
      director text PATH '$.director' KEEP QUOTES))) AS jt;

 id |   kind   |  title  |      director
----+----------+---------+--------------------
  1 | horror   | Psycho  | "Alfred Hitchcock"
  2 | thriller | Vertigo | "Alfred Hitchcock"
(2 rows)

次の問い合わせは、ルートパスにフィルタを指定しない場合と同じです。

SELECT jt.* FROM
 my_films,
 JSON_TABLE ( js, '$.favorites[*]'
   COLUMNS (
    id FOR ORDINALITY,
    kind text PATH '$.kind',
    NESTED PATH '$.films[*]' COLUMNS (
      title text FORMAT JSON PATH '$.title' OMIT QUOTES,
      director text PATH '$.director' KEEP QUOTES))) AS jt;

 id |   kind   |      title      |      director
----+----------+-----------------+--------------------
  1 | comedy   | Bananas         | "Woody Allen"
  1 | comedy   | The Dinner Game | "Francis Veber"
  2 | horror   | Psycho          | "Alfred Hitchcock"
  3 | thriller | Vertigo         | "Alfred Hitchcock"
  4 | drama    | Yojimbo         | "Akira Kurosawa"
(5 rows)

次に異なるJSONオブジェクトを入力として使用する別の問い合わせを示します。 これは、NESTEDパスである$.movies[*]$.books[*]との間のUNION”兄弟結合”(sibling join)を示しています。 また、NESTEDレベルでのFOR ORDINALITY列(列movie_idbook_id、およびauthor_id)の使用を示しています。

SELECT * FROM JSON_TABLE (
'{"favorites":
    {"movies":
      [{"name": "One", "director": "John Doe"},
       {"name": "Two", "director": "Don Joe"}],
     "books":
      [{"name": "Mystery", "authors": [{"name": "Brown Dan"}]},
       {"name": "Wonder", "authors": [{"name": "Jun Murakami"}, {"name":"Craig Doe"}]}]
}}'::json, '$.favorites[*]'
COLUMNS (
  user_id FOR ORDINALITY,
  NESTED '$.movies[*]'
    COLUMNS (
    movie_id FOR ORDINALITY,
    mname text PATH '$.name',
    director text),
  NESTED '$.books[*]'
    COLUMNS (
      book_id FOR ORDINALITY,
      bname text PATH '$.name',
      NESTED '$.authors[*]'
        COLUMNS (
          author_id FOR ORDINALITY,
          author_name text PATH '$.name'))));

 user_id | movie_id | mname | director | book_id |  bname  | author_id | author_name
---------+----------+-------+----------+---------+---------+-----------+--------------
       1 |        1 | One   | John Doe |         |         |           |
       1 |        2 | Two   | Don Joe  |         |         |           |
       1 |          |       |          |       1 | Mystery |         1 | Brown Dan
       1 |          |       |          |       2 | Wonder  |         1 | Jun Murakami
       1 |          |       |          |       2 | Wonder  |         2 | Craig Doe
(5 rows)