一、postgresql實用函數
(只列舉本次用到的函數,其他函數在文章后面有詳解)
1.1、將jsonb格式的數組中的值展開/分解成單獨的數據/對象?
SELECT answer_id,? jsonb_array_elements(option_ids)::INTEGER? AS option_id
FROM db_live_answer?
WHERE survey_code='No.20230605165428002'
?
?
1.2、如何根據對象id將jsonb數組展開到每個jsonb列的對象中?
?如果所有json數組都包含兩個新列的兩個元素,那么使用固定路徑,如dmfay的答案。 否則,你應該使用jsonb_array_elements()兩次取消數組,分別為text_id_one
和text_id_two
。
update sample t set
text_id_one = value1,
text_id_two = value2
from sample s,
jsonb_array_elements(s.metadata_array) as e1(value1),
jsonb_array_elements(s.metadata_array) as e2(value2)
where s.id = t.id
and value1->>'id' = 'textIdOne'
and value2->>'id' = 'textIdTwo'
returning t.*
如果數組中有兩個以上的元素,則此變體可能更高效(也更方便):
update sample t
set
text_id_one = arr1->0,
text_id_two = arr2->0
from (
select
id,
jsonb_agg(value) filter (where value->>'id' = 'textIdOne') as arr1,
jsonb_agg(value) filter (where value->>'id' = 'textIdTwo') as arr2
from sample,
jsonb_array_elements(metadata_array)
group by id
) s
where t.id = s.id
returning t.*
例子來源:如何根據對象id將jsonb數組展開到每個jsonb列的對象中?
2、postgresql操作符的使用
一、 -> 和 ->>? (適用于操作數組) :
-> 表示獲取一個JSON數組元素,支持下標值(下標從0開始)、Key獲取。
->> 表示獲取一個JSON對象字符串。
代碼:
SELECT '[{"a":1},{"b":2},{"c":3}]'::JSON -> 1;
結果:
{"b":2}
以上,::JSON 表示聲明前面的字符串為一個JSON字符串對象,而且PostgreSQL中的JSON、JSONB對象 Key的聲明必須是字符串 。同時,1表示獲取JSON數組中下標值為1的JSON對象。
接下來,看下 ->> 的用法:
代碼:
SELECT '[{"a":1},{"b":2},{"c":3}]'::JSON ->> 1;
結果:
{"b":2}
以上,->> 的查詢結果和 -> 對比不太直觀,我們可以進一步驗證。
連用:
代碼:
SELECT '[{"a":1},{"b":2},{"c":3}]'::JSON -> 1 -> 'b';
結果:
2
以上,我們可以看到首先我們使用下標的方式,獲取JSON數組中下標值為1的JSON對象 {"b":2}。然后,我們通過Key的方式來獲取這個JSON對象的Value值,結果是 2。
接下來,我們測試下 ->> 的方式來獲取:
代碼:
SELECT '[{"a":1},{"b":2},{"c":3}]'::JSON ->> 1 -> 'b';
?
報錯:
[SQL]SELECT '[{"a":1},{"b":2},{"c":3}]'::JSON ->> 1 -> 'b';
?
[Err] 錯誤: ?操作符不存在: text -> unknown
LINE 1: SELECT '[{"a":1},{"b":2},{"c":3}]'::JSON ->> 1 -> 'b';
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?^
HINT: ?No operator matches the given name and argument types. You might need to add explicit type casts.
以上,可以看到錯誤提示操作符不存在,因為第一步查詢出來的是一個字符串,不是JSON對象。
改成正確提取方式:
代碼:
SELECT ('[{"a":1},{"b":2},{"c":3}]'::JSON ->> 1)::JSON -> 'b';
結果:
2
以上,可以看到現(xiàn)在可以正確查詢出結果,我們將第一步查詢出來的字符串轉成JSON對象,然后通過 Key 的方式來獲取 Value。不過,這種查詢方式相對于 -> 來說還是比較繁瑣的。
二、 #> 和 #>>?(適用于操作對象) :
在前一步,我們在一個JSON數組中可以使用 -> 下標值的方式來獲取一個JSON對象。但是,如果我們我們檢索的不是JSON數組,而是一個JSON對象中的JSON對象。很顯然,這種下標獲取的方式不再適用。不過,我們可以使用下面的方式來獲取。
#> 表示獲取指定路徑的一個JSON對象,
#>>表示獲取指定路徑的一個JSON對象的字符串。
代碼:
SELECT '{"a":1,"b":{"ba":"b1","bb":"b2"},"c":3}'::JSON #> ''
結果:
{"ba":"b1","bb":"b2"}
以上,我們使用 #> 方式來獲取一個JSON對象中的JSON對象。
注意:
在獲取一個JSON對象時,除非是JSON數組中的下標,必須要要用 { } 將JSON對象的 Key 包裹起來,否則會拋出異常。
代碼:
SELECT '{"a":1,"b":{"ba":"b1","bb":"b2"},"c":3}'::JSON#>'b'
結果:
[Err] 錯誤: ?有缺陷的數組常量:"b"
LINE 1: SELECT '{"a":1,"b":{"ba":"b1","bb":"b2"},"c":3}'::JSON#>'b'
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ^
DETAIL: ?數組值必須以 "{" 或者維度信息開始。
同樣的,我們還可以在 #> 的基礎上,繼續(xù)獲取這個JSON對象內的相關信息。
代碼:
SELECT '{"a":1,"b":{"ba":"b1","bb":"b2"},"c":3}'::JSON#>''->'ba'
結果:
"b1"
??????以上,可以看到 -> 獲取的是一個JSON對象。->>是獲取的一個text 文本
二、PostgreSQL 操作符、函數
json和jsonb 操作符
操作符 | 右操作數類型 | 描述 | 例子 | 例子結果 |
-> | int | 獲得 JSON 數組元素(索引從 0 開始,負整數從末尾開始計) | [{"a":"foo"},{"b":"bar"},{"c":"baz"}]'::json->2 | {"c":"baz"} |
-> | text | 通過鍵獲得 JSON 對象域 | {"a": {"b":"foo"}}'::json->'a' | {"b":"foo"} |
->> | int | 以text形式獲得 JSON 數組元素 | [1,2,3]'::json->>2 | 3 |
->> | text | 以text形式獲得 JSON 對象域 | {"a":1,"b":2}'::json->>'b' | 2 |
#> | text[] | 獲取在指定路徑的 JSON 對象 | {"a": {"b":{"c": "foo"}}}'::json#>'{a,b}' | {"c": "foo"} |
#>> | text[] | 以text形式獲取在指定路徑的 JSON 對象 | {"a":[1,2,3],"b":[4,5,6]}'::json#>>'{a,2}' | 3 |
額外的jsonb
操作符
操作符 | 右操作數類型 | 描述 | 例子 |
@> | jsonb | 左邊的 JSON 值是否在頂層包含右邊的 JSON 路徑/值項? | {"a":1, "b":2}'::jsonb @> '{"b":2}'::jsonb |
<@ | jsonb | 左邊的 JSON 路徑/值項是否被包含在右邊的 JSON 值的頂層? | {"b":2}'::jsonb <@ '{"a":1, "b":2}'::jsonb |
? | text | 鍵/元素字符串是否存在于 JSON 值的頂層? | {"a":1, "b":2}'::jsonb ? 'b' |
?| | text[] | 這些數組字符串中的任何一個是否做為頂層鍵存在? | {"a":1, "b":2, "c":3}'::jsonb ?| array['b', 'c'] |
?& | text[] | 是否所有這些數組字符串都作為頂層鍵存在? | ["a", "b"]'::jsonb ?& array['a', 'b'] |
|| | jsonb | 把兩個jsonb值串接成一個新的jsonb值 | ["a", "b"]'::jsonb || '["c", "d"]'::jsonb |
- | text | 從左操作數刪除鍵/值對或者string 元素。鍵/值對基于它們的鍵值來匹配。 | {"a": "b"}'::jsonb - 'a' |
- | text[] | 從左操作數中刪除多個鍵/值對或者string元素。鍵/值對基于它們的鍵值來匹配。 | {"a": "b", "c": "d"}'::jsonb - '{a,c}'::text[] |
- | integer | 刪除具有指定索引(負值表示倒數)的數組元素。如果 頂層容器不是數組則拋出一個錯誤。 | ["a", "b"]'::jsonb - 1 |
#- | text[] | 刪除具有指定路徑的域或者元素(對于 JSON 數組,負值 表示倒數) | ["a", {"b":1}]'::jsonb #- '{1,b}' |
JSON 創(chuàng)建函數
函數 | 描述 | 例子 | 例子結果 |
to_json(anyelement)? to_jsonb(anyelement) | ??? 把該值返回為json或者jsonb。數組和組合 會被(遞歸)轉換成數組和對象;對于不是數組和組合的值,如果有 從該類型到json的造型,造型函數將被用來執(zhí)行該 轉換;否則將產生一個標量值。對于任何不是數字、布爾、空值的標 量類型,將使用文本表達,在這種風格下它是一個合法的 json或者jsonb值。 | to_json('Fred said "Hi."'::text) | Fred said \Hi.\"" |
array_to_json(anyarray [, pretty_bool]) | ??? 把數組作為一個 JSON 數組返回。一個 PostgreSQL 多維數組會成為一個數組 的 JSON 數組。如果pretty_bool為真,將在 第 1 維度的元素之間增加換行。 | array_to_json('{{1,5},{99,100}}'::int[]) | [[1,5],[99,100]] |
row_to_json(record [, pretty_bool]) | ??? 把行作為一個 JSON 對象返回。如果pretty_bool為真,將在第1層元素之間增加換行。 | row_to_json(row(1,'foo')) | {"f1":1,"f2":"foo"} |
json_build_array(VARIADIC "any")?? jsonb_build_array(VARIADIC "any") | ??? 從一個可變參數列表構造一個可能包含異質類型的 JSON 數組。 | json_build_array(1,2,'3',4,5) | [1, 2, "3", 4, 5] |
json_build_object(VARIADIC "any")?? jsonb_build_object(VARIADIC "any") | ??? 從一個可變參數列表構造一個 JSON 對象。通過轉換,該參數列表由交替 出現(xiàn)的鍵和值構成。 | json_build_object('foo',1,'bar',2) | {"foo": 1, "bar": 2} |
json_object(text[])? jsonb_object(text[]) | ??? 從一個文本數組構造一個 JSON 對象。該數組必須可以是具有偶數個成員的 一維數組(成員被當做交替出現(xiàn)的鍵/值對),或者是一個二維數組(每一個 內部數組剛好有 2 個元素,可以被看做是鍵/值對)。 | json_object('{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[])? jsonb_object(keys text[], values text[]) |
?json_object的這種形式從兩個獨立的數組得到鍵/值對。在其 他方面和一個參數的形式相同。 | json_object('{a, b}', '{1,2}') | {"a": "1", "b": "2"} |
JSON 處理?
函數 | 返回值 | 描述 | 例子 | 例子結果 |
json_array_length(json)? jsonb_array_length(jsonb) | int | 返回最外層 JSON 數組中的元素數量。 | json_array_length('[1,2,3,{"f1":1,"f2":[5,6]},4]') | 5 |
json_each(json)? jsonb_each(jsonb) |
setof key text, value json setof key text, value jsonb |
擴展最外層的 JSON 對象成為一組鍵/值對。 | select * from json_each('{"a":"foo", "b":"bar"}') | ?key | value -----+------- ?a?? | "foo" ?b?? | "bar" |
json_each_text(json)? jsonb_each_text(jsonb) | setof key text, value text | 擴展最外層的 JSON 對象成為一組鍵/值對。返回值將是text類型。 | 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[])?? jsonb_extract_path(from_json jsonb, VARIADIC path_elems text[]) | json jsonb |
返回由path_elems指向的 JSON 值(等效于#>操作符)。 | json_extract_path('{"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}','f4') | {"f5":99,"f6":"foo"} |
json_extract_path_text(from_json json, VARIADIC path_elems text[])? jsonb_extract_path_text(from_json jsonb, VARIADIC path_elems text[])? | text | 以text返回由path_elems指向的 JSON 值(等效于#>>操作符)。 | json_extract_path_text('{"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}','f4', 'f6') | foo |
json_object_keys(json)? jsonb_object_keys(jsonb) | setof text | 返回最外層 JSON 對象中的鍵集合。 | json_object_keys('{"f1":"abc","f2":{"f3":"a", "f4":"b"}}') | json_object_keys ------------------ ?f1 ?f2 |
json_populate_record(base anyelement, from_json json)? jsonb_populate_record(base anyelement, from_json jsonb) | anyelement | 擴展from_json中的對象成一個行,它的列匹配由base定義的記錄類型(見下文的注釋)。 | select * from json_populate_record(null::myrowtype, '{"a": 1, "b": ["2", "a b"], "c": {"d": 4, "e": "a b c"}}') | ?a |?? b?????? |????? c ---+-----------+------------- ?1 | {2,"a b"} | (4,"a b c") |
json_populate_recordset(base anyelement, from_json json)? jsonb_populate_recordset(base anyelement, from_json jsonb) | setof anyelement | 擴展from_json中最外的對象數組為一個集合,該集合的列匹配由base定義的記錄類型。 | select * from json_populate_recordset(null::myrowtype, '[{"a":1,"b":2},{"a":3,"b":4}]') | ?a | b ---+--- ?1 | 2 ?3 | 4 |
json_array_elements(json)? jsonb_array_elements(jsonb) | setof json setof jsonb |
把一個 JSON 數組擴展成一個 JSON 值的集合。 | select * from json_array_elements('[1,true, [2,false]]') | value ----------- ?1 ?true ?[2,false] |
json_array_elements_text(json)? jsonb_array_elements_text(jsonb) | setof text | 把一個 JSON 數組擴展成一個text值集合。 | select * from json_array_elements_text('["foo", "bar"]') | ? value ----------- ?foo ?bar |
json_typeof(json)? jsonb_typeof(jsonb) | text | 把最外層的 JSON 值的類型作為一個文本字符串返回??赡艿念愋褪牵?object、array、string、number、 boolean以及null。 | json_typeof('-123.4') | number |
json_to_record(json)? jsonb_to_record(jsonb) | record | 從一個 JSON 對象(見下文的注解)構建一個任意的記錄。正如所有返回record 的函數一樣,調用者必須用一個AS子句顯式地定義記錄的結構。 | 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)? jsonb_to_recordset(jsonb) | setof record | 從一個 JSON 對象數組(見下文的注解)構建一個任意的記錄集合。正如所有返回record 的函數一樣,調用者必須用一個AS子句顯式地定義記錄的結構。 | select * from json_to_recordset('[{"a":1,"b":"foo"},{"a":"2","c":"bar"}]') as x(a int, b text); | ?a |? b ---+----- ?1 | foo ?2 | |
json_strip_nulls(from_json json)? jsonb_strip_nulls(from_json jsonb) | json jsonb |
返回from_json,其中所有具有空值的 對象域都被省略。其他空值不動。 | json_strip_nulls('[{"f1":1,"f2":null},2,null,3]') | [{"f1":1},2,null,3] |
jsonb_set(target jsonb, path text[], new_value jsonb[, create_missing boolean]) | jsonb | 返回target,其中由 path指定的節(jié)用 new_value替換,如果 path指定的項不存在并且 create_missing為真(默認為 true)則加上 new_value。正如面向路徑的 操作符一樣,出現(xiàn)在path中的 負整數表示從 JSON 數組的末尾開始數。 | jsonb_set('[{"f1":1,"f2":null},2,null,3]', '{0,f1}','[2,3,4]', false) jsonb_set('[{"f1":1,"f2":null},2]', '{0,f3}','[2,3,4]') | [{"f1":[2,3,4],"f2":null},2,null,3][{"f1": 1, "f2": null, "f3": [2, 3, 4]}, 2] |
jsonb_insert(target jsonb, path text[], new_value jsonb, [insert_after boolean]) | jsonb | 返回被插入了new_value的target。如果path指定的target節(jié)在一個 JSONB 數組中,new_value將被插入到目標之前(insert_after為false,默認情況)或者之后(insert_after為真)。如果path指定的target節(jié)在一個 JSONB 對象內,則只有當target不存在時才插入new_value。對于面向路徑的操作符來說,出現(xiàn)在path中的負整數表示從 JSON 數組的末尾開始計數。 | jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '"new_value"')? jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '"new_value"', true) | {"a": [0, "new_value", 1, 2]}? {"a": [0, 1, "new_value", 2]} |
jsonb_pretty(from_json jsonb) | text | 把from_json返回成一段 縮進后的 JSON 文本。 | jsonb_pretty('[{"f1":1,"f2":null},2,null,3]') | [ ??? { ??????? "f1": 1, ??????? "f2": null ??? }, ??? 2, ??? null, ??? 3 ] |
?參考:PostgreSQL中JSON函數和操作符_function jsonb_set(json, unknown, unknown) does no_EngineerForSoul的博客-CSDN博客文章來源:http://www.zghlxwxcb.cn/news/detail-477774.html
postgresql 關于JSON、JSONB操作符以處理函數_postgresql json函數_谷滿滿的博客-CSDN博客文章來源地址http://www.zghlxwxcb.cn/news/detail-477774.html
到了這里,關于Postgresql關于JSON、JSONB的操作符、處理函數(持續(xù)更新)的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!