问题描述
我的数据库中有这个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
,
您将需要爆炸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)