JSONB到数组数据类型

时间:2018-12-20 05:40:23

标签: sql arrays json postgresql jsonb

我目前有一个表会话,其中包含列action(JSONB)。

我可以使用array_to_jsonb(array value)从前端将数组正确存储到数据库中。

我的数组的结构(数组值)如下:

var arrayStructure = [
    {name: 'email client', check: false},
    {name: 'send contract', check: false}
]

与我在SO上看到的许多有关修改JSONB或访问某些键的问题不同,我只想将整个JSONB数据转换回前端的数组。

我的临时解决方法是映射整个数组,并使用Javascript中的JSON.parse()重组数组中的每个对象。我无法在整个数组上使用JSON.parse(),因为它会引发错误。

我正在寻找将数组格式恢复为存储的JSONB数据类型的查询。我看过JSONB_SET,LATERAL和JSONB_ARRAY_ELEMENTS_TEXT。但是,这种方式无法恢复适当的数组。

开头为:表中名为会话的动作列中的JSONB

结果应为::该查询将带回所有行,但将操作列(JSONB)转换回前端的数组:

select session_id, session_name, someFunction or lateral here(actions) from sessions

Screenshot of Sessions Table

我尝试过这样的查询:

SELECT 
   session_id, 
   actions::jsonb -> 'name' as name
FROM sessions;

并返回名称的null。我已经尝试过->>来访问更深层次的内容,但这也不起作用。

这是正确查询结果的一半:

select session_id, jsonb_array_elements_text(actions)
from sessions
group by session_id;

这将导致以下结果(仅注意session_id为264的结果): query result

现在我在自己的行中有对象,如下:

 {"name": "some task", "check": "false} 

当我想要的操作列是:

[ {name: "some task", check: false}, {name: "other task", check: true} ]

因此,我需要进一步解析JSON并按session_id进行分组。我只是在努力建立一个做到这一点的子查询。

创建设置的步骤:

create table fakeSessions (
session_id serial primary key, 
name varchar(20), 
list jsonb
)

insert into fakeSessions(name, list)
VALUES(
'running',
'["{\"name\":\"inquired\",\"check\":false}", "{\"name\":\"sent online guide\",\"check\":false}", "{\"name\":\"booked!\",\"check\":false}"]'
)

insert into fakeSessions(name, list)
VALUES(
'snowboarding',
'["{\"name\":\"rental\",\"check\":false}", "{\"name\":\"booked ski passes\",\"check\":false}", "{\"name\":\"survey\",\"check\":false}"]'
)

我创建的最接近的查询:

with exports as (
    select jsonb_array_elements_text(actions)::jsonb as doc from sessions
)
select array_agg(doc) from
exports, sessions
group by session_id;

获取文本值,然后将聚合函数应用于返回的那些行。只是无法使select array_agg(doc)正常工作。最可能是因为我需要在那个地方使用其他功能。

2 个答案:

答案 0 :(得分:1)

有帮助吗?

demo:db<>fiddle

jsonb_array_elements()
  1. jsonbjsonb数组扩展为每个jsonb_agg()元素一行
  2. jsonb将这些 map<string,map<string,map<string,decimal>>> mapData = new map<string,map<string,map<string,decimal>>>(); //get all events for(Event e: eventLst){ string dateKey = dateMapKey(e.CreatedDate); map<string,map<string,decimal>> bmap = new map<string,map<string,decimal>>(); map<string,decimal> fieldMap = new map<string,decimal>(); if(mapData.get(dateKey) != null){ bmap = mapData.get(datekey); if(bmap.get(e.Booker__c) != null){ fieldMap = bmap.get(e.Booker__c); } } decimal countShow=0,countNoShow=0,showPerc=0; if(fieldMap.get('countShow') != null){ countShow = fieldMap.get('countShow'); } if(fieldMap.get('countNoShow') != null){ countNoShow = fieldMap.get('countNoShow'); } if(fieldMap.get('countNoShow') != null && fieldMap.get('countShow') != null){ showPerc = fieldMap.get('showPerc'); } if(e.Booking_Status__c == 'Show'){ countShow++; } if(e.Booking_Status__c == 'No Show'){ countNoShow++; } showPerc = countNoShow != 0 ? (countShow / (countShow + countNoShow)* 100).setScale(1) : 0.0; map<string,decimal> fm = new map<string,decimal>(); fm.put('countShow',countShow); fm.put('countNoShow',countNoShow); fm.put('showPerc',showPerc); map<string,map<string,decimal>> bm = new map<string,map<string,decimal>>(); bm.put(e.Booker__c,fm); mapData.put(dateKey,bm); } 元素聚合为一个大数组。

答案 1 :(得分:1)

我能够通过建立您的查询来找到答案!非常感谢。获得预期结果的查询是:

with exports as (
    select session_id, jsonb_array_elements_text(actions)::jsonb as doc from sessions
)
select session_id, jsonb_agg(doc) from exports
group by session_id;

一旦获得元素,就不再使用jsonb_agg()函数。获得准确格式的区别只是使用jsonb_array_elements_text::jsonb