如何在postgres jsonb中使用BETWEEN?

时间:2017-04-24 09:01:08

标签: sql postgresql jsonb

我有一些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';

还有其他想法吗?感谢〜

2 个答案:

答案 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)这样的东西。)

http://rextester.com/GAA60634