Postgres选择JSON数组并重新Map属性名

iqih9akk  于 4个月前  发布在  其他
关注(0)|答案(2)|浏览(53)

在执行SELECT查询时,我需要重新Mappostgres中数组对象的属性名称。
user_phones具有列idphones。假设phones列类型为json,数组具有以下结构:

[
  {
    model: "samsung s23 utra",
    serial_number: 123456
  },
  {
    model: "apple i-phone 15",
    serial_number: 123477
  }
]

字符串
当我执行select查询时,我希望在响应中返回phones属性:

[
  {
    model: "samsung s23 utra",
    serialNumber: 123456
  },
  {
    model: "apple i-phone 15",
    serialNumber: 123477
  }
]


我想的是沿着SELECT p.id, json_build_array(SELECT <this is where I'm stuck>) as p.phones FROM user_phones as p的沿着;
我添加了fiddle here
有没有一个简单的方法在postgres中执行此操作?

rjzwgtxy

rjzwgtxy1#

转换为textreplace(),转换回jsonDemo at db<>fiddle

select id, replace(phones::text,'"serial_number"','"serialNumber"')::json
from user_phones;

字符串
| ID| jsonb_漂亮|
| --|--|
| 1 |的    {        “model”:“samsung s23 utra”,        “serialNumber”:“12345”    },    {        “model”:“iphone15”,        “serialNumber”:“12333”    }]的一种|
它将针对任何匹配模式的对象,不管它实际上是键还是值,或者两者的一部分。从好的方面来说,它更简单,更快,并且让你不必担心数组中对象的当前和未来结构。
如果你解构,重命名,重构,你会失去你没有显式寻址的结构的所有元素的键和值,每当一个元素有一个丢失或重命名的键,或者有一些额外的数据。
另一种摆脱盲文本替换缺点的方法是使用jsonb操作符-删除旧键,并使用||重新添加新名称:

select id, json_agg(   e - 'serial_number'
                    || jsonb_build_object('serialNumber',e->'serial_number') )
from user_phones,jsonb_array_elements(phones::jsonb)_(e) 
group by 1;


这样,你就可以在每个对象中只重命名键,而不需要对它周围的结构做任何假设。注意,从json to jsonb切换将压缩无关紧要的空白,以及对键进行排序和重复数据删除。

xuo3flqw

xuo3flqw2#

使用json_array_elements()函数将JSON数组扩展为多行,然后应用json_build_object重构JSON元素,最后使用json_agg()将这些元素合并回JSON数组。

SELECT id, json_agg(
              json_build_object('model', value->'model', 'serialNumber', value->'serial_number')::json
           ) new_json
FROM user_phones u
CROSS JOIN json_array_elements(u.phones) 
GROUP BY id

字符串
结果如下:

id  new_json
1   [{"model" : "samsung s23 utra", "serialNumber" : 123456}, {"model" : "apple i-phone 15", "serialNumber" : 123477}]


Demo here

相关问题