是否可以在不创建函数且不使用任何服务器端编程语言的情况下转换
jsonb
数据?我正在使用 Postgres 9.4。
CREATE TABLE test (id SERIAL PRIMARY KEY,data JSONB);
INSERT INTO test(data) VALUES('{"a":1,"b":2}');
INSERT INTO test(data) VALUES('{"a":3,"b":4,"c":7}');
INSERT INTO test(data) VALUES('{"a":5,"b":5,"d":8}');
SELECT * FROM test;
id | data
----+-------------------------
1 | {"a": 1, "b": 2}
2 | {"a": 3, "b": 4, "c": 7}
3 | {"a": 5, "b": 5, "d": 8}
将其转换为类似以下内容:
{1:[1,2,null,null]
, 2:[3,4,7,null]
, 3:[5,5,null,8]}
jsonb_populate_record()
(或 json_populate_record()
表示 json
),并将已注册的行类型作为目标。这是最快的,每个值都会隐式转换为目标字段的类型。如果不存在具有匹配行类型的表(类对象),则使用临时复合类型进行临时使用:
CREATE TYPE pg_temp.my_obj AS (a int, b int, c int, d int);
(临时对象在会话结束时被销毁,我们只需要一个模板。)
参见:
然后:
SELECT t.id, d.*
FROM test t, jsonb_populate_record(null::my_obj, t.data) d;
jsonb_to_record()
(或json_to_record()
表示json
)并通过调用提供列定义列表:
SELECT t.id, d.*
FROM test t, jsonb_to_record(t.data) d(a int, b int, c int, d int);
或分别提取并投射每个字段:
SELECT id
, (data->>'a')::int AS a, (data->>'b')::int AS b
, (data->>'c')::int AS c, (data->>'d')::int AS d
FROM test;
相关:
创建新的数据类型。
create type fourints as (a int, b int,c int,d int);
然后:
SELECT t.id, d.*
FROM test1 t
, jsonb_populate_record(null::fourints, t.data) d;