下載客戶端:https://www.enterprisedb.com/downloads/postgres-postgresql-downloads
json和jsonb的區別
postgresql支持兩種json數據類型:json和jsonb,而兩者唯一的區別在於效率,json是對輸入的完整拷貝,使用時再去解析,所以它會保留輸入的空格,重複鍵以及順序等。而jsonb是解析輸入後保存的二進制,它在解析時會刪除不必要的空格和重複的鍵,順序和輸入可能也不相同。使用時不用再次解析。兩者對重複鍵的處理都是保留最後一個鍵值對。效率的差別:json類型存儲快,使用慢,jsonb類型存儲稍慢,使用較快。
注意:鍵值對的鍵必須使用雙引號
jsonb類型
建表語句
CREATE TABLE "public"."test_json_tbl" (
"id" int4 ,
"name" TEXT,
"json_value" jsonb
);
--設置id爲自增序列
CREATE SEQUENCE "public"."test_json_tbl_id_seq"
INCREMENT 1
MINVALUE 1
MAXVALUE 99999999
START 1
CACHE 1;
--設置該序列爲此表id主鍵
alter table "public"."test_json_tbl" alter column id set default nextval('test_json_tbl_id_seq');
--測試設置序列是否成功
SELECT nextval('public.test_json_tbl_id_seq');
--設置爲主鍵
alter table test_json_tbl add primary key (id) ;
1.插入
insert into test_json_tbl (name,json_value)
VALUES
('test1','{"name":"jack","home":"江西南昌","values":["a","b"]}')
往json字符串中添加元素 比如增加年齡字段 備註:如果json_value爲json類型則不能這樣操作,||是針對jsonb的操作符,意思爲拼接,如果jsonb中包含此字段則會進行替換。
update test_json_tbl set json_value=
(
SELECT json_value ||'{"age":"12"}'::jsonb FROM test_json_tbl
where json_value->>'name'='jack'
)
where json_value->>'name'='jack';
結果:
id name json_value
1 test1 {"age": "12", "home": "江西南昌", "name": "jack", "values": ["a", "b"]}
--替換
select '{"name":"abc"}'::jsonb || '{"name":"aaa"}'::jsonb as name;
結果:
{"name": "aaa"}
--新增 或 合併
select '{"name":"abc"}'::jsonb || '{"age":"18"}'::jsonb as person;
結果:
{"age": "18", "name": "abc"}
摘自:https://blog.csdn.net/u011944141/article/details/82912365
如果 select null||'{"name":"hmm"}' 此時是無法合併的,則需要外加一個判斷
如:
update test_json_tbl set json_value = (
CASE
WHEN json_value is null
THEN
'[{"age":"age", "name":"name"}]'
ELSE
json_value || '[{"age":"13", "name":"hmm2"}]'
END
)
where id=4;
大佬指導:
update rows of a table Syntax: [ WITH [ RECURSIVE ] with_query [, ...] ] UPDATE [ ONLY ] table_name [ * ] [ [ AS ] alias ] SET { column_name = { expression | DEFAULT } | ( column_name [, ...] ) = [ ROW ] ( { expression | DEFAULT } [, ...] ) | ( column_name [, ...] ) = ( sub-SELECT ) } [, ...] [ FROM from_list ] [ WHERE condition | WHERE CURRENT OF cursor_name ] [ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]
既然它可以是一個 expression, 那下邊這個就是可以的:
update jinbo.jsonb_table1 set extend = ( case when extend is null then '[{"age":"age", "name":"name"}]' else extend || '[{"age":"age", "name":"name"}]' end ) where id = 6;
感謝:https://blog.csdn.net/u011944141/article/details/82912365#comments
2.查詢
select id,name,json_value from test_json_tbl where json_value->>'name'='jack'
結果:id name json_value
1 test1 {"name":"jack","home":"江西南昌","values":["a","b"]}
SELECT json_value->>'home' as home from test_json_tbl where json_value->>'name'='jack'
結果:
home
江西南昌
SELECT json_value->>'name' as name FROM test_json_tbl;--返回文本,不帶引號
結果:
name
jack
SELECT json_value->'name' as name FROM test_json_tbl;--返回json類型,就是原聲的,帶引號的
結果:
name
"jack"
SELECT json_value->'values'#>'{1}' as name FROM test_json_tbl;--獲取json的子對象,就是map中key爲values中的第1個元素 #>>返回文本
結果:
name
"b"
3.更新
update test_json_tbl set json_value='{"name":"jack2","home":"江西南昌2","values":["a","b"]}' where json_value->>'name1'='jack1'
結果:
id name json_value
1 test1 {"name":"jack2","home":"江西南昌2","values":["a","b"]}
4.刪除
DELETE from test_json_tbl where json_value->>'name'='jack2'
json數組
json數組的遍歷:
INSERT into test_json_tbl ("id","name",json_value) VALUES (2,'humm','
[
{"age":12,"name":"tom"},
{"age":12,"name":"tom2"},
{"age":12,"name":"tom3"}
]');
顯示名字集合
SELECT jsonb_array_elements((SELECT json_value FROM test_json_tbl where id=2))#>>'{name}' as namelist;
namelist
tom1
tom2
tom3
json數組元素的插入(增加)
UPDATE test_json_tbl set json_value=json_value||'[{"age": 12, "name": "tom4"}]'::jsonb where id=2;
結果:
[{"age": 12, "name": "tom"}, {"age": 12, "name": "tom2"}, {"age": 12, "name": "tom3"}, {"age": 12, "name": "tom4"}]
備註:->>返回text 一般用於通過key拿到字符串,不帶引號
-> 返回原聲對象 一般用於通過key拿到json對象,帶引號
json_array_elements(jsonAry)展開這個json數組的各元素
那如果本身數據庫存儲的類型字段就是json數組呢?那又該如何在每一行都是json數組找到自己想要的元素呢?(這裏枚舉兩處)
首先先要把每一行的數組轉成豎着的,那這裏也就是6行了
SELECT id_test_table,jsonb_array_elements(json_value) json_element FROM test_table
那後面只需要加條件就行了,蔽日我要找到age=1的數據
SELECT id_test_table,json_element from
(
SELECT id_test_table,jsonb_array_elements(json_value) json_element FROM test_table
) t
WHERE t.json_element->>'age'=1||''
PostgreSQL 9.5以上的版本中有了很多方便的操作符(例如:json字段->>json字段的key 通過key找到對應的json數據)
json和jsonb的操作符
操作符 | 右操作數類型 | 描述 | 示例 | 結果 |
-> | int | 獲取JSON數組元素(索引從0開始) | select '[{"a":"foo"},{"b":"bar"},{"c":"baz"}]'::json->2; | {"c":"baz"} |
-> | text | 通過鍵獲取值,返回原聲對象 | select '{"a": {"b":"foo"}}'::json->'a'; | {"b":"foo"} |
->> | int |
獲取JSON數組元素爲 text |
select '[1,2,3]'::json->>2; | 3 |
->> | text | 通過鍵獲取值爲text | select '{"a":1,"b":2}'::json->>'b'; | 2 |
#> |
text[] 這裏應該寫json |
在指定的路徑獲取JSON對象 |
select '{"a": {"b":{"c": "foo"}}}'::json#>'{a,b}'; | {"c": "foo"} |
#>> |
text[] 這裏應該寫json |
在指定的路徑獲取JSON對象爲 text |
select '{"a":[1,2,3],"b":[4,5,6]}'::json#>>'{a,2}'; | 3 |
jsonb額外操作符
操作符 | 右操作數類型 | 描述 | 示例 | 結果 |
@> | jsonb | 左側json最上層的值是否包含右邊json對象 |
select '{"a":{"b":2}}'::jsonb @> '{"b":2}'::jsonb; select '{"a":1, "b":2}'::jsonb @> '{"b":2}'::jsonb; |
f t |
<@ | jsonb | 左側json對象是否包含於右側json最上層的值內 | select '{"b":2}'::jsonb <@ '{"a":1, "b":2}'::jsonb; | t |
? | text | text是否作爲左側Json對象最上層的鍵 | select '{"a":1, "b":2}'::jsonb ? 'b'; | t |
?| | text[] | text[]中的任一元素是否作爲左側Json對象最上層的鍵 | select '{"a":1, "b":2, "c":3}'::jsonb ?| array['b', 'c']; | t |
?& | text[] | text[]中的所有元素是否作爲左側Json對象最上層的鍵 | select '["a", "b"]'::jsonb ?& array['a', 'b']; | t |
|| | jsonb | 連接兩個json對象,組成一個新的json對象 | select '["a", "b"]'::jsonb || '["c", "d"]'::jsonb; | ["a", "b", "c", "d"] |
- | text | 刪除左側json對象中鍵爲text的鍵值對 | select '{"a": "b"}'::jsonb - 'a'; | {} |
- | integer |
刪除數組指定索引處的元素,如果索引值爲負數,則從右邊計算索引值。 如果最上層容器內不是數組,則拋出錯誤。 |
select '["a", "b"]'::jsonb - 1; | ["a"] |
#- | text[] |
刪除指定路徑下的域或元素(如果是json數組,且整數值是負的, 則索引值從右邊算起) |
select '["a", {"b":1}]'::jsonb #- '{1,b}'; | ["a", {}] |
json創建函數
函數 | 描述 | 示例 | 結果 |
to_json(anyelement) to_jsonb(anyelement) |
返回json或jsonb類型的值。數組和複合被轉換(遞歸)成數組和對象。另外除數字、 布爾、NULL值(直接使用NULL拋出錯誤)外,其他標量必須有類型轉換。(此處請參考原文) |
select to_json('3'::int); | 3 |
array_to_json(anyarray [, pretty_bool]) |
以JSON數組返回該數組。PostgreSQL多維數組變成JSON數組中的數組。 |
select array_to_json('{{1,5},{99,100}}'::int[],true); |
[[1,5], + |
row_to_json(record [, pretty_bool]) | 以JSON對象返回行。如果pretty_bool 爲真,則在級別1元素之間添加換行。 | select row_to_json(row(1,'foo'),true); |
{"f1":1, + |
json_build_array(VARIADIC "any") jsonb_build_array(VARIADIC "any") |
建立一個由可變參數列表組成的不同類型的JSON數組 | select json_build_array(1,2,'3',4,5); | [1, 2, "3", 4, 5] |
json_build_object(VARIADIC "any") jsonb_build_object(VARIADIC "any") |
建立一個由可變參數列表組成的JSON對象。參數列表參數交替轉換爲鍵和值。 | select json_build_object('foo',1,'bar',2); | {"foo" : 1, "bar" : 2} |
json_object(text[]) jsonb_object(text[]) |
根據text[]數組建立一個json對象,如果是一維數組,則必須有偶數個 元素,元素交替組成鍵和值。如果是二維數組,則每個元素必須有2個元素,可以組成鍵值對。 |
select json_object('{a, 1, b, "def", c, 3.5}'); select 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[]) |
分別從兩組text[]中獲取鍵和值,與一維數組類似。 | select json_object('{a, b}', '{1,2}'); | {"a" : "1", "b" : "2"} |
json處理函數
函數 | 返回類型 | 描述 | 示例 | 結果 |
json_array_length(json) jsonb_array_length(jsonb) |
int | 返回Json數組最外層元素個數 | select 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 json_each('{"a":"foo", "b":"bar"}'); |
(a,"""foo""") |
json_each_text(json) jsonb_each_text(jsonb) |
setof key text, value text | 將最外層Json對象轉換爲鍵值對集合,且value爲text類型 | select json_each_text('{"a":"foo", "b":"bar"}'); |
(a,foo) |
json_extract_path(from_json json, VARIADIC path_elems text[])
jsonb_extract_path(from_json jsonb, VARIADIC path_elems text[]) |
json jsonb |
返回path_elems指向的value,同操作符#> | select 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 | 返回path_elems指向的value,並轉爲text類型,同操作符#>> | select 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對象最外層的key | select json_object_keys('{"f1":"abc","f2":{"f3":"a", "f4":"b"}}'); |
f1 |
json_populate_record(base anyelement, from_json json)
jsonb_populate_record(base anyelement, from_json jsonb) |
anyelement | 將json對象的value以base定義的行類型返回,如果行類型字段比json對象鍵值少,則多出的鍵值將被拋棄;如果行類型字段多,則多出的字段自動填充NULL。 |
表tbl_test定義:
Table "public.tbl_test" c | character varying(32) |
select * from json_populate_record(null::tbl_test, '{"a":1,"b":2}');
|
a | b | c |
json_populate_recordset(base anyelement, from_json json)
jsonb_populate_recordset(base anyelement, from_json jsonb) |
setof anyelement | 將json對象最外層數組以base定義的行類型返回 |
表定義同上 select * from json_populate_recordset(null::tbl_test, '[{"a":1,"b":2},{"a":3,"b":4}]'); |
a | b | c |
json_array_elements(json) jsonb_array_elements(jsonb) |
setof json setof jsonb |
將json數組轉換成json對象value的集合 | select json_array_elements('[1,true, [2,false]]'); |
1 |
json_array_elements_text(json) jsonb_array_elements_text(jsonb) |
setof text | 將json數組轉換成text的value集合 | select json_array_elements_text('["foo", "bar"]'); |
foo |
json_typeof(json) jsonb_typeof(jsonb) |
text |
返回json最外層value的數據類型,可能的類型有 object, array, string, number, boolean, 和null. |
select json_typeof('-123.4') | number |
json_to_record(json) jsonb_to_record(jsonb) |
record | 根據json對象創建一個record類型記錄,所有的函數都返回record類型,所以必須使用as明確定義record的結構。 | select * from json_to_record('{"a":1,"b":[1,2,3],"c":"bar"}') as x(a int, b text, d text); |
a | b | d |
json_to_recordset(json) jsonb_to_recordset(jsonb) |
setof record | 根據json數組創建一個record類型記錄,所有的函數都返回record類型,所以必須使用as明確定義record的結構。 | select * from json_to_recordset('[{"a":1,"b":"foo"},{"a":"2","c":"bar"}]') as x(a int, b text); |
a | b |
json_strip_nulls(from_json json) jsonb_strip_nulls(from_json jsonb) |
json jsonb |
返回json對象中所有非null的數據,其他的null保留。 |
select 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 | 如果create_missing爲true,則將在target的path處追加新的jsonb;如果爲false,則替換path處的value。 |
select jsonb_set('[{"f1":1,"f2":null},2,null,3]', '{0,f1}','[2,3,4]', false);
select 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 | 如果insert_after是true,則在target的path後面插入新的value,否則在path之前插入。 |
select jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '"new_value"');
select 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 | 以縮進的格式更容易閱讀的方式返回json對象 | select jsonb_pretty('[{"f1":1,"f2":null},2,null,3]'); |
[ |