基于通配符密钥查询嵌套的json

时间:2018-02-06 20:39:16

标签: postgresql jsonb

我有一个PostgresQL表,它将JSON存储为jsonb:

 Column |  Type   |                         Modifiers                         | Storage  | Stats target | Description 
--------+---------+-----------------------------------------------------------+----------+--------------+-------------
 id     | integer | not null default nextval('history_id_seq'::regclass)      | plain    |              | 
 data   | jsonb   | not null                                                  | extended |              | 

JSON的结构:

{
    "20180201": {
        "foo": [{
            "name": "item1",
            "desc": "an item 1"
        }, {
            "name": "item2",
            "desc": "an item 2"
        }],
        "bar": [{
            "name": "item1",
            "desc": "an item 1"
        }, {
            "name": "item2",
            "desc": "an item 2"
        }]
    }
}

每一行都包含一个JSON,其中timestamp是字典的关键字。

我想编写一个查询,从每行的JSON中获取所有foo

我这样做是先获取所有密钥(在Python中执行此操作):

SELECT (jsonb_object_keys(data)) AS key FROM history;

然后迭代所有键,我运行查询(python伪代码):

for key in keys: 
    query = "SELECT data->'%s'->'foo'FROM history" % key
    fetch_and_print_all_rows()

我该怎么做才是单个查询,而不是先获取所有键,然后迭代并获取foo项。由于用作密钥的时间戳可以是任何东西,因此可以执行SELECT data->'%'->'foo' FROM history

之类的操作

1 个答案:

答案 0 :(得分:2)

使用jsonb_each():

select id, key, value->>'foo' as foo
from history
cross join jsonb_each(data)

 id |   key    |                                       foo                                        
----+----------+----------------------------------------------------------------------------------
  1 | 20180201 | [{"desc": "an item 1", "name": "item1"}, {"desc": "an item 2", "name": "item2"}]
(1 row)