sql - 使用嵌套 JSON 数组上的过滤器进行选择

标签 sql json postgresql greatest-n-per-group

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/

相关文章:

json - 使用静态 json 文件作为源的 jQuery UI 自动完成

python - 使用 JSON 功能读取 CSV

postgresql - plpgsql:调用带有 2 个 OUT 参数的函数

sql - 将 JSON 扩展为以第一行为模板的列

sql - SQL 中的 ORDER BY

java - 从 API 检索艺术家 ID——将它们处理为 long 还是 int?

java搜索-从字符串preparedstatement中获取整数值

python - 注释相关模型中注释值的总和

sql - 简化 MS SQL 语句

sql - 如何在不区分大小写的 Oracle DB 中返回不同的记录?