Download Client: https://www.enterprisedb.com/downloads/postgres-postgresql-downloads
The difference between json and jsonb
json postgresql supports two types of data: json and jsonb, the only difference is that their efficiency, a complete copy of json input, again using parsing, so it will not leave a space input key, and the sequence is repeated and the like. The jsonb is saved after parsing binary input, it will remove unnecessary spaces and duplicate keys, and enter the order may not be the same while parsing. Without parsing again use. Both deal with duplicate keys are reserved for the last key-value pair. Differences in efficiency: json type of storage faster, use slow, jsonb slower type of memory, using faster.
Note: The key value pairs must use double quotes
jsonb type
Construction of the table statement
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
insert into test_json_tbl (name,json_value)
VALUES
('test1','{"name":"jack","home":"江西南昌","values":["a","b"]}')
Json string to add elements such as increasing age field Note: If the type json json_value is not doing so, is directed jsonb || operator, meaning splicing, if this field contains jsonb will be replaced.
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. Query
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
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
DELETE from test_json_tbl where json_value->>'name'='jack2'
json array
json array traversal:
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
Insert json array elements (increase)
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"}]
Notes: - >> return key to get the text string are generally used by, without quotation marks
-> Back Soundtrack for objects typically get through key json object quoted
json_array_elements (jsonAry) to expand the array of elements json
What if the database itself is stored in the type field json array it? Then how to find the array elements they want in each row is json it? (Enumerate here two)
First, each row of the array should first turn into a bristling, that here is the line 6
SELECT id_test_table,jsonb_array_elements(json_value) json_element FROM test_table
That behind only need to add conditions on the line, I want to find Biri age = 1 data
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]'); | [ |