从jsonb postgres数组中选择元素

问题描述

我的数据库中有这个jsonb。 当且仅当前一个元素处于状态3时,我才需要显示处于状态1的元素

我需要进行查询,使我得到满足条件的元素。

可以和postgres一起使用吗?

Foo

解决方法

您可以将json数组取消嵌套到子查询中的行,然后使用window函数检索“上一个”数组元素。然后剩下要做的就是过滤。

假设您的json(b!)数据存储在表js的列mytable中,则可以这样表述:

select x.obj
from mytable t
cross join lateral (
    select x.obj,lag(obj) over(order by rn) lag_obj
    from jsonb_array_elements(t.js) with ordinality as x(obj,rn)
) x
where (obj ->> 'state')::int = 1 and (lag_obj ->> 'state')::int = 3

Demo on DB Fiddle

,

您将需要爆炸json来实现:

with invars as (
  select 1 as id,' [
    {
        "state": 3,"activity": "EJECUCIÓN","final_date": "2020-02-24","activity_id": 1,"current_days": -7,"initial_date": "2020-02-24"

    },{
        "state": 1,"activity": "REVISIÓN","final_date": "2020-02-25","activity_id": 2,"current_days": 0,"initial_date": "2020-02-25"

    },{
        "state": 0,"activity": "RECEPCIÓN","final_date": "2020-02-27","activity_id": 4,"initial_date": "2020-02-27"


    } ]'::jsonb as jcol
),expand as (
  select i.id,j.obj->>'state' as this_state,lag(j.obj->>'state') 
           over (partition by id
                     order by rn) as last_state,j.obj
    from invars i
         cross join lateral 
           jsonb_array_elements(jcol) 
             with ordinality as j(obj,rn)
)
select *
  from expand
 where this_state = '1' 
   and last_state = '3'
;
┌────┬────────────┬────────────┬─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ id │ this_state │ last_state │                                                                 obj                                                                 │
├────┼────────────┼────────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│  1 │ 1          │ 3          │ {"state": 1,"initial_date": "2020-02-25"} │
└────┴────────────┴────────────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
(1 row)