我有一个表,其中包含一个JSONB字段和一个JSON数组,并具有我想扩展的简单格式。这是表格定义的简化版本:
CREATE TABLE IF NOT EXISTS data.data_file_info (
id uuid NOT NULL,
server_name_ citext NOT NULL,
table_stats jsonb DEFAULT '{}'::jsonb NOT NULL,
PRIMARY KEY(id)
);
以下是来自table_stats JSONB字段的一些示例数据:
[
{"table_name":"AutoReportOrg","record_count":48,"table_number":167},
{"table_name":"AutoReportOrgAudit","record_count":0,"table_number":170},
{"table_name":"AutoReportOrgRecipient","record_count":126,"table_number":168},
{"table_name":"AutoReportRecipient","record_count":28,"table_number":169}
]
json_populate_recordset和/或json_to_recordset函数似乎应该是我所追求的,但是我无法使其正常工作。我查看了很多过去的问题,并尝试了各种语法。以下是我得到的印象应该起作用的信息……但事实并非如此:
-- Define a custom type to act as a template for the JSON parser.
DROP TYPE IF EXISTS dfits;
CREATE TYPE api.dfits AS (
table_name citext,
record_count int8,
table_number int4);
-- And now we parse!
SELECT server_name_, (json_populate_recordset(null::dfits, table_stats)).* FROM data_file_info;
但是我回来了:
ERROR: function json_populate_recordset(dfits, jsonb) does not exist
LINE 4: SELECT server_name_, (json_populate_recordset(null::dfits, t...
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts. (Line 9)
有人可以发现我的设置中的错误吗?看来我有合适的作品,但我没有设法将它们正确地组合在一起。
已部署在RDS上的Postgres 11.4。
GMB回答了我的问题,但是我想在这里为档案添加更多内容。经过我的输入错误(JSON而不是JSONB)之后,这些问题的症结似乎在于Postgres需要一个模板/映射来定义JSON / JSONB数组中元素的结构。我认为在这种情况下,可以在四个(?)地方输入数据:
CREATE TYPE
创建的自定义类型,就像我上面使用的那样。为进行比较,下面是一个更新的查询,该查询使用上面显示的自定义类型dfits
:
SELECT server_name_, expanded_json.*
FROM
data_file_info,
jsonb_populate_recordset(null::dfits, table_stats) as expanded_json
现在这是另一个使用嵌入式声明的版本:
SELECT server_name_, expanded_json.*
FROM
data_file_info,
jsonb_to_recordset(table_stats) as expanded_json
(table_name text, record_count int, table_number int)
我可以看到这两种方法的用处。但是,话虽这么说,CREATE TYPE
确实很棒。而且,您可以将其与CREATE CAST
结合使用,以生成非常紧凑且易于使用的代码。
答案 0 :(得分:2)
由于您使用的是jsonb
列,因此您实际上需要jsonb_populate_recordset
。另外,此函数返回一组记录,因此需要将其放在FROM
子句中,而不是SELECT
子句中。
考虑:
SELECT server_name, x.*
FROM
data_file_info,
jsonb_populate_recordset(null::dfits, table_stats) x
| server_name | table_name | record_count | table_number |
| ----------- | ---------------------- | ------------ | ------------ |
| foo | AutoReportOrg | 48 | 167 |
| foo | AutoReportOrgAudit | 0 | 170 |
| foo | AutoReportOrgRecipient | 126 | 168 |
| foo | AutoReportRecipient | 28 | 169 |