我有一些jsonb数据,如:
{
"id":"58fd893414a570155ddf5120",
"TPDId":"10101",
"Services":[
"10093"
],
"DaysInstances":[
17304,
17300,
17301,
17302,
17303
],
"TPDProperties":{
"DisplayLabel":"TP display label W0ichP6h",
"TimePeriodType":"Maintenance"
}
}
字段 DaysInstances 是一个数组。
现在我想要选择记录 DaysInstances 的值介于17300和17303之间。
我试过这种sql但没用:
SELECT body FROM "TimePeriodInstance_100000001" where (body -> 'DaysInstances') between '17300' AND '17303';
这个sql工作但现在很难在我们的系统中拼接:
SELECT DISTINCT body FROM "TimePeriodInstance_100000001" cross join
json_array_elements((body -> 'DaysInstances')::json) where value::text::int between '17300' AND '17303';
还有其他想法吗?感谢〜
答案 0 :(得分:1)
尝试:
(Works,如果jsons id
字段对每一行都是唯一的)
select test1.* from test1 inner join (
select json_id from (
select col->>'id' as json_id, jsonb_array_elements_text(col->'DaysInstances') as arrel from test1
)t where arrel::numeric between 17300 and 17303
GROUP BY json_id
) t2
on test1.col->>'id' = t2.json_id
如果您有唯一的标识列(例如id
),那么最好使用它:
select test1.* from test1 inner join (
select id from (
select id, jsonb_array_elements_text(col->'DaysInstances') as arrel from test1
)t where arrel::numeric between 17300 and 17303
GROUP BY id
) t2
on test1.id = t2.id
答案 1 :(得分:1)
你可以在没有聚合的情况下做到这一点。 LATERAL
,带有一个普通的相关子查询(带EXISTS
):
SELECT body
FROM "TimePeriodInstance_100000001"
WHERE EXISTS(SELECT 1
FROM jsonb_array_elements(body -> 'DaysInstances') e
WHERE e BETWEEN '17300' AND '17303')
注意:BETWEEN
约束实际上(隐式)键入jsonb
,它有比较运算符来备份它。如果你想绑定int
的f.ex.,你需要使用强制转换才能使它工作(或使用像BETWEEN to_jsonb($1) AND to_jsonb($2)
这样的东西。)