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
您需要分解 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)
我的数据库中有这个 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
您需要分解 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)