Postgres查询嵌套JSONB

时间:2020-02-20 07:34:57

标签: sql postgresql timescaledb

我有一个JSONB列,其中包含list的{​​{1}}。>
这是表模式:

objects

样本数据

1。

column Name | Datatype
---------------------
timestamp   | timestamp
  data      | JSONB 
timestamp : 2020-02-02 19:01:21.571429+00

2。

data : [
  {
    "tracker_id": "5",
    "position": 1
  },
  {
    "tracker_id": "11",
    "position": 2
  },
  {
    "tracker_id": "4",
    "position": 1
  }
]
timestamp : 2020-02-02 19:01:23.571429+00

3。

data : [
  {
    "tracker_id": "7",
    "position": 3
  },
  {
    "tracker_id": "4",
    "position": 2
  }
]
timestamp : 2020-02-02 19:02:23.571429+00

我需要找到data : [ { "tracker_id": "5", "position": 2 }, { "tracker_id": "4", "position": 1 } ] tracker_idposition: 1的转变次数
在这里,输出将为position: 2,因为2 tracker_id4的{​​{1}}从5更改为{{1 }}。

注意
过渡应该按照position
升序排列 1更改不必在连续记录中。
我正在使用timescaledb扩展名

到目前为止,我已经尝试查询单个记录的列表对象,但是我不确定如何合并每个记录的列表对象并对其进行查询。

对此的查询是什么?我应该写下一个存储过程吗?

2 个答案:

答案 0 :(得分:1)

有多种功能可将多个数据库行组合到一个JSON结构中:row_to_json(),array_to_json()和array_agg()。

然后,您将使用带有ORDER BY子句的常规SELECT来获取所需的时间戳/ JSON数据,并使用上述函数来创建单个JSON结构。

答案 1 :(得分:1)

我不使用timescaledb扩展名,所以我会基于嵌套json选择纯SQL解决方案:

with t (timestamp,data) as (values
  (timestamp '2020-02-02 19:01:21.571429+00', '[
  {
    "tracker_id": "5",
    "position": 1
  },
  {
    "tracker_id": "11",
    "position": 2
  },
  {
    "tracker_id": "4",
    "position": 1
  }
]'::jsonb),
  (timestamp '2020-02-02 19:01:23.571429+00', '[
  {
    "tracker_id": "7",
    "position": 3
  },
  {
    "tracker_id": "4",
    "position": 2
  }
]
'::jsonb),
  (timestamp '2020-02-02 19:02:23.571429+00', '[
  {
    "tracker_id": "5",
    "position": 2
  },
  {
    "tracker_id": "4",
    "position": 1
  }
]
'::jsonb)
), unnested as (
  select t.timestamp, r.tracker_id, r.position
  from t
  cross join lateral jsonb_to_recordset(t.data) AS r(tracker_id text, position int)
)
select count(*)
from unnested u1
join unnested u2
  on u1.tracker_id = u2.tracker_id
 and u1.position = 1 
 and u2.position = 2
 and u1.timestamp < u2.timestamp;