在postgres中使用jsonb_each和LATERAL查询JSONB中的ID

时间:2017-06-18 17:10:08

标签: sql postgresql jsonb

想象一个超级简单的表,例如:

create table object (
    id INT,
    data jsonb
);

有些数据:

INSERT INTO object (id, data) VALUES
  (4, '{"nodes":{"f":{"id":1}}}'), -- C
  (5, '{"nodes":{"d":{"id":2}, "e":{"id":3}}}'), -- B
  (6, '{"nodes":{"b":{"id":4}, "c":{"id":5}}}') -- A
;

我想要解构JSON并查询孩子。

例如,如果我这样做

SELECT * FROM jsonb_each('{"a":{"id":1},"b":{"id":2}}'::JSONB) as obj

我会回来的:

a   {"id":1}
b   {"id":2}

我正在尝试将此结合起来从嵌套对象中获取id属性并查询子项(没有运气):

SELECT
      jsonb_each(data->'nodes')
      FROM objects as objs
      WHERE id=6
      LATERAL (SELECT * FROM objects as ref WHERE ref.id = objs->'id');

如果有帮助,我提供了一个SQL小提琴:http://sqlfiddle.com/#!17/50fb2/9

编辑:

这是一个示例输出:

id  data
4   '{"nodes":{"f":{"id":1}}}'
5   '{"nodes":{"d":{"id":2}, "e":{"id":3}}}'

再次感谢您对此有任何见解!

2 个答案:

答案 0 :(得分:1)

此查询从jsonb对象中提取ids

select (value->>'id')::int as nested_id
from object,
jsonb_each(data->'nodes')
where id = 6;

 nested_id 
-----------
         4
         5
(2 rows)    

在join中使用它作为派生表:

select o.*
from object o
join (
    select (value->>'id')::int as nested_id
    from object,
    jsonb_each(data->'nodes')
    where id = 6
    ) s
on id = nested_id;

 id |                    data                     
----+---------------------------------------------
  4 | {"nodes": {"f": {"id": 1}}}
  5 | {"nodes": {"d": {"id": 2}, "e": {"id": 3}}}
(2 rows)

或作为运算符in的子查询:

select o.*
from object o
where id in (
    select (value->>'id')::int as nested_id
    from object,
    jsonb_each(data->'nodes')
    where id = 6
    );

但是,这也可以通过横向查询(如您所愿)完成:

select s.*
from object o,
jsonb_each(data->'nodes'),
lateral (select * from object where id = (value->>'id')::int) s
where o.id = 6;

答案 1 :(得分:0)

不确定,但可能你需要这个:

SELECT object.id, key, value 
FROM object
JOIN LATERAL jsonb_each(data->'nodes')
ON (value->>'id')::int  = object.id
WHERE 
object.id = 6