聚合 json 数组中特定键的值 - PostgreSQL

Posted

技术标签:

【中文标题】聚合 json 数组中特定键的值 - PostgreSQL【英文标题】:Aggregating values of particular key in json array - PostgreSQL 【发布时间】:2021-09-24 03:34:08 【问题描述】:

我有一个类似格式的表格:

chat_id |                                                                                                                                         agent_details                                                   
---------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 chat_1  | ["agentId": "agent01", "transferFromAgentName": "e2eagent01", "agentId": "nemo-user", "transferFromAgentName": "N/A", "agentId": "salesdemo-nemo-user-e2eagent01", "transferFromAgentName": "e2eagent05", "agentId": "salesdemo-nemo-user-e2eagent01", "transferFromAgentName": "N/A"]
 chat_1  | ["agentId": "agent01", "transferFromAgentName": "agent5", "agentId": "nemo-user", "transferFromAgentName": "agent6", "agentId": "salesdemo-nemo-user-e2eagent01", "transferFromAgentName": "N/A"]

我需要在 GROUP BY 语句中提取与每个 chat_id 关联的所有 transferFromAgentName

我尝试了以下查询,但我只能从agent_details 列中读取第一个transferFromAgentName

select 
chat_id, 
array_remove(ARRAY_AGG(DISTINCT agent_details::json->0  ->> 'transferFromAgentName'), 'N/A') 
FROM 
temp.chatsession 
GROUP BY chat_id;

给出以下输出:

chat_id |    array_remove
---------+---------------------
 chat_1  | agent5,e2eagent01

我要求所有transferFromAgentName 都出现在第二列中,即e2eagent01,e2eagent05,agent5,agent6

创建和插入查询:

CREATE TABLE chatsession (
  chat_id varchar(20),
  agent_details JSONB
);

INSERT INTO chatsession
VALUES ('chat_1', '[
    
        "agentId": "agent01",
        "transferFromAgentName": "e2eagent01"
    ,
    
        "agentId": "nemo-user",
        "transferFromAgentName": "N/A"
    ,
    
        "agentId": "salesdemo-nemo-user-e2eagent01",
        "transferFromAgentName": "e2eagent05"
    ,
    
        "agentId": "salesdemo-nemo-user-e2eagent01",
        "transferFromAgentName": "N/A"
    
]'),
('chat_1', '[
    
        "agentId": "agent01",
        "transferFromAgentName": "agent5"
    ,
    
        "agentId": "nemo-user",
        "transferFromAgentName": "agent6"
    ,
    
        "agentId": "salesdemo-nemo-user-e2eagent01",
        "transferFromAgentName": "N/A"
    
]');

【问题讨论】:

您使用的是哪个 Postgres 版本? SELECT version() 返回PostgreSQL 13.3, compiled by Visual C++ build 1914, 64-bit 所以你想要e2eagent01,N/A,e2eagent05,N/A,agent5,agent6,N/A 作为结果? 是的,删除所有N/A 也是如此。所以e2eagent01,e2eagent05,agent5,agent6 【参考方案1】:

您需要先取消嵌套数组,然后才能聚合来自不同行的元素。

select c.chat_id, 
       array_agg(d.item ->> 'transferFromAgentName')
from chatsession c
  cross join jsonb_array_elements(c.agent_details) as d(item)
where d.item ->> 'transferFromAgentName' <> 'N/A'  
group by c.chat_id  

【讨论】:

以上是关于聚合 json 数组中特定键的值 - PostgreSQL的主要内容,如果未能解决你的问题,请参考以下文章

如何在一个列上进行分组,在另一个列上聚合数组并创建一个由分组列作为键的 JSON 对象

如何使用Javascript读取json文件并将特定键的值写入同一json文件中?

使用 NSPredicate 仅从字典数组中获取特定键的值

JavaScript - 有没有一种简单的方法来获取嵌套 JSON 中每次出现的特定键的值

如何从自定义模型对象数组中获取特定键的值

从数组中的所有对象中获取特定键的值