我有一个表,其中包含一个 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)
有人能发现我的设置中的错误吗?看起来我已经找到了正确的部分,但我无法将它们正确地组合在一起。
Postgres 11.4,部署在 RDS 上。
跟进
GMB 回答了我的问题,但我想在此处添加更多内容以供存档。过去我的打字错误(JSON 而不是 JSONB),这个问题的关键似乎是 Postgres 需要一个模板/映射来定义 JSON/JSONB 数组中元素的结构。我认为在这种情况下,可以从四个(?)地方输入数据:
- 现有的表定义,因为每个表都是一种类型。
- 现有 View 定义,因为每个 View 都是一种类型。 (您可以在 pg_class 中找到它们以及基表派生类型。
- 使用
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
结合起来,形成非常紧凑且易于使用的代码。
最佳答案
由于您使用的是 jsonb
列,因此您实际上需要 jsonb_populate_recordset
。另外,该函数返回一组记录,因此需要将其放在 FROM
子句中,而不是放在 SELECT
子句中。
考虑:
SELECT server_name, x.*
FROM
data_file_info,
jsonb_populate_recordset(null::dfits, table_stats) x
<强> Demo on DB Fiddle :
| server_name | table_name | record_count | table_number |
| ----------- | ---------------------- | ------------ | ------------ |
| foo | AutoReportOrg | 48 | 167 |
| foo | AutoReportOrgAudit | 0 | 170 |
| foo | AutoReportOrgRecipient | 126 | 168 |
| foo | AutoReportRecipient | 28 | 169 |
关于sql - 扩展存储在 JSONB 中的对象数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58243737/