select 个来自 jsonb postgres 数组的元素

select elements from jsonb postgres array

我的数据库中有这个 jsonb。 当且仅当前一个元素处于状态 3

时,我才需要显示处于状态 1 的元素

我需要进行查询,给我带来满足条件的元素。

可以用 postgres 吗?

 [
    {
        "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,
        "current_days": 0,
        "initial_date": "2020-02-27"


    } ]

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

假设您的 json(b!) 数据存储在 table mytable 的第 js 列中,您可以将其表述为:

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,
        "current_days": 0,
        "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, "activity": "REVISIÓN", "final_date": "2020-02-25", "activity_id": 2, "current_days": 0, "initial_date": "2020-02-25"} │
└────┴────────────┴────────────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
(1 row)