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"}
]
我正在努力按日期和时间添加两个过滤器。像(非法伪代码!):
WHERE 'type' = "indiv"
或类似:
WHERE 'type' = "indiv"AND max('date')
这可能很容易,但我无法破解这个难题,需要你的帮助!
最佳答案
由于缺少信息,假设数据类型为 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"}]'
相关:
关于sql - 使用嵌套 JSON 数组上的过滤器进行选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47896450/