在嵌套的JSON数组上选择过滤器

问题描述 投票:1回答:1

Postgres 10:我有一张表和一个查询如下:

CREATE TABLE individuals (
    uid character varying(10) PRIMARY KEY,
    data jsonb
);

SELECT data->'files'  FROM individuals WHERE uid = 'PDR7073706'

它返回这个结构:

[
{"date":"2017-12-19T22-35-49","type":"indiv","name":"PDR7073706_indiv_2017-12-19T22-35-49.jpeg"},
{"date":"2017-12-19T22-35-49","type":"address","name":"PDR7073706_address_2017-12-19T22-35-49.pdf"}
]

我正在努力按日期和时间添加两个过滤器。喜欢(非法的伪代码!):

在哪里'type'=“indiv”

或者喜欢:

在哪里'type'=“indiv”和最大('日期')

这可能很容易,但我无法破解这个坚果,需要你的帮助!

sql json postgresql greatest-n-per-group
1个回答
1
投票

假设数据类型jsonb缺乏信息。 使用包含运算符@>作为第一个子句(WHERE'type'=“indiv”):

SELECT data->'files'
FROM   individuals
WHERE  uid = 'PDR7073706'
AND    data -> 'files' @> '[{"type":"indiv"}]';

可以支持各种索引。看到:

第二个子句(AND max('date'))更棘手。假设你的意思是: 获取带有"type":"indiv"的JSON数组元素也具有最新"date"的行。

SELECT i.*
FROM   individuals i
JOIN   LATERAL (
   SELECT *
   FROM   jsonb_array_elements(data->'files')
   ORDER  BY to_timestamp(value ->> 'date', 'YYYY-MM-DD"T"HH24-MI-SS') DESC NULLS LAST
   LIMIT  1
   ) sub ON sub.value -> 'type' = '"indiv"'::jsonb
WHERE  uid = 'PDR7073706'
AND    data -> 'files' @> '[{"type":"indiv"}]' -- optional; may help performance

to_timestamp(value ->> 'date', 'YYYY-MM-DD"T"HH24-MI-SS')是我对未申报时间戳格式的有根据的猜测。 Details in the manual here.

最后一个过滤器是冗余和可选的。但如果它是有选择性的(只有几行合格)并且你有一个匹配的索引,它可能有助于性能(很多):

AND    data -> 'files' @> '[{"type":"indiv"}]'

有关:

© www.soinside.com 2019 - 2024. All rights reserved.