Postgresql将JSONB对象更新为数组
我不知道为什么,但可能PHP将我的一些数据持久化为对象,而将其中一些数据持久化为数组。我的桌子看起来像: 卖方信息地址表:Postgresql将JSONB对象更新为数组,sql,jsonb,postgresql-10,Sql,Jsonb,Postgresql 10,我不知道为什么,但可能PHP将我的一些数据持久化为对象,而将其中一些数据持久化为数组。我的桌子看起来像: 卖方信息地址表: ID (INT) | address (JSONB) | ------------+--------------------------------------------------| 1 | {"addressLines":{"0":&qu
ID (INT) | address (JSONB) |
------------+--------------------------------------------------|
1 | {"addressLines":{"0":"Technology Park",...},...} |
2 | {"addressLines":["Technology Park",...],...} |
某些地址行是对象:
{
"addressLines": {
"0": "Technology Park",
"1": "Blanchard Road",
"3": "Dublin",
"4": "2"
},
"companyName": "...",
"emailAddress": [],
"...": "..."
}
有些地址行是数组:
{
"addressLines": [
"Technology Park",
"Blanchard Road",
"Dublin",
"2"
],
"companyName": "...",
"emailAddress": [],
"...": "..."
}
我想用SQL查询来均衡数据,但我不知道该怎么做。所有持久化为对象的地址行
都应更新为数组形式
我很感谢你的帮助,谢谢 您可以使用以下方法将对象转换为数组:
select id, (select jsonb_agg(e.val order by e.key::int)
from jsonb_each(sia.address -> 'addressLines') as e(key,val))
from seller_info_address sia
where jsonb_typeof(address -> 'addressLines') = 'object'
where条件确保我们只对不是数组的地址行执行此操作
使用的聚合也可以在UPDATE语句中使用:
update seller_info_address
set address = jsonb_set(address, '{addressLines}',
(select jsonb_agg(e.val order by e.key::int)
from jsonb_each(address -> 'addressLines') as e(key,val))
)
where jsonb_typeof(address -> 'addressLines') = 'object';
好的,我现在自己找到了一个解决办法。绝对不是最有说服力的解决方案。我相信有一个更好更高效的,但它很有效
DROP FUNCTION update_address_object_to_array(id INTEGER);
内部选择使用jsonb_each
获取addressLines
对象中的所有行,然后使用jsonb_agg
将它们聚合到一个数组中。条件表达式用于防止出现空情况
然后通过
jsonb_set
将结果存储在更新中的json中所需的位置。何处应该是不言自明的。引人入胜,几乎同时也是同样的解决方案。我想我们是灵魂伴侣。谢谢你的麻烦!我也遇到了同样的问题,来这里是为了清理数据。数据有时是数组,有时是对象,这是因为php数组必须基于0才能被视为数组。看见
CREATE OR REPLACE FUNCTION
update_address_object_to_array(id INTEGER)
RETURNS VOID AS
$UPDATE_ADDRESS_OBJECT_TO_ARRAY$
BEGIN
UPDATE seller_info_address
SET address = jsonb_set(address, '{addressLines}', (
SELECT CASE
WHEN jsonb_agg(addressLines) IS NOT NULL THEN jsonb_agg(addressLines)
ELSE '[]'
END
FROM seller_info_address sia,
jsonb_each(address #> '{addressLines}') as t(key, addressLines)
WHERE jsonb_typeof(sia.address -> 'addressLines') = 'object'
AND seller_info_id = update_address_object_to_array.id
), true)
WHERE seller_info_id = update_address_object_to_array.id
AND jsonb_typeof(address -> 'addressLines') = 'object';
END
$UPDATE_ADDRESS_OBJECT_TO_ARRAY$
LANGUAGE 'plpgsql';
SELECT update_address_object_to_array(sia.seller_info_id)
FROM seller_info_address sia
WHERE jsonb_typeof(address -> 'addressLines') = 'object';