在jsonb Postgresql字段中的特定索引/位置添加数组

时间:2018-02-12 14:09:51

标签: arrays postgresql sorting jsonb

我想知道是否有办法将数组附加到Postgresql 9.6中jsonb数组中的特定索引/位置?

让我们想象下面的代码是我的json:

{
  "date": "2018-02-12",
  "author": "devoplex",
  "block": [
    { "color": "#C70039", "title": "Fruit" },
    { "color": "#DAF7A6", "title": "Vegetable" },
    { "color": "#DAF7A6", "title": "Meat" }
  ]
}

我想在“块”数组中附​​加此对象:

{ "color": "#581845", "title": "Candy" }

但是我希望这个对象成为第三个索引/位置而不替换任何东西。所以最后我可以得到这个结果:

{
  "date": "2018-02-12",
  "author": "devoplex",
  "block": [
    { "color": "#C70039", "title": "Fruit" },      <---- Initial line
    { "color": "#DAF7A6", "title": "Vegetable" },  <---- Initial line
    { "color": "#581845", "title": "Candy" },      <---- New line
    { "color": "#DAF7A6", "title": "Meat" }        <---- Initial line
  ]
}

这个例子不是我的实际代码,但它是同一个问题。这是用于构建表单,因此它需要按特定顺序进行,否则就没有任何意义。谢谢你。

1 个答案:

答案 0 :(得分:0)

一个丑陋的轮子,但没有什么比这更聪明了:

with c(jb) as (values('{
  "date": "2018-02-12",
  "author": "devoplex",
  "block": [
    { "color": "#C70039", "title": "Fruit" },
    { "color": "#DAF7A6", "title": "Vegetable" },
    { "color": "#DAF7A6", "title": "Meat" }
  ]
}'::jsonb))
, m as (select jb,e,case when o <3 then o else o+1 end o from c, jsonb_array_elements(jb->'block') with ordinality t(e,o) union all select jb, '{ "color": "#581845", "title": "Candy" }',3 from c)
, n as (select distinct jb,jsonb_agg(e) over (order by o) a from m)
select jsonb_pretty(jsonb_set(jb,'{block}',a)) from n order by length(a::text) desc limit 1;
           jsonb_pretty
----------------------------------
 {                               +
     "date": "2018-02-12",       +
     "block": [                  +
         {                       +
             "color": "#C70039", +
             "title": "Fruit"    +
         },                      +
         {                       +
             "color": "#DAF7A6", +
             "title": "Vegetable"+
         },                      +
         {                       +
             "color": "#581845", +
             "title": "Candy"    +
         },                      +
         {                       +
             "color": "#DAF7A6", +
             "title": "Meat"     +
         }                       +
     ],                          +
     "author": "devoplex"        +
 }

当然,如果你想在其他索引中使用其他数字,你应该将3替换为其他数字... http://dbfiddle.uk/?rdbms=postgres_10&fiddle=ccef24ef615b30eec07be9d1be5a1f8d这里的例子,索引从主要查询中取出,用于CTE