如何在Postgres 9.3中搜索JSON数组中的多个项目

时间:2016-06-09 22:00:12

标签: json postgresql-9.3

我有需要在JSON数组中搜索多个值的场景。以下是我的架构。

   ID            DATA
   1           {"bookIds" : [1,2,3,5], "storeIds": [2,3]} 
   2           {"bookIds" : [1,2], "storeIds": [1,3]}
   3           {"bookIds" : [11,12,10,9], "storeIds": [4,3]}

我想要所有值为1,2的行。下面是我正在使用的查询(这是查询是由其他一个stackoverflow用户klin先生写给他的。)

  select t.*
  from JSONTest t, json_array_elements(data->'bookIds') books
  where books::text::int in (1, 2);

但是输出我在输出中是重复的行,下面是我的输出。

     id      data
     1       {"bookIds" : [1,2,3,5], "storeIds": [2,3]}
     1       {"bookIds" : [1,2,3,5], "storeIds": [2,3]}
     2       {"bookIds" : [1,2], "storeIds": [1,3]}
     2       {"bookIds" : [1,2], "storeIds": [1,3]}

我只希望输出中有两行是id 1,2。我怎样才能做到这一点?由于其他限制,我不想使用Distinct,

SQL小提琴:http://sqlfiddle.com/#!15/6457a/2

1 个答案:

答案 0 :(得分:1)

不幸的是,从JSON数组到“真正的”Postgres数组没有直接转换函数。 (data ->'bookIds')::text返回的内容几乎是Postgres数组文字:例如[1,2,3,5]。如果将[]替换为{},则可以将值转换为整数数组。一旦我们有了一个正确的整数数组,我们可以使用@>来测试它是否包含另一个数组:

select *
from jsontest
where translate((data ->'bookIds')::text, '[]', '{}')::int[] @> array[1,2];

translate((data ->'bookIds')::text, '[]', '{}')会将[1,2,3,5]转换为{1,2,3,5},然后使用::int[]转换为数组

SQLFiddle:http://sqlfiddle.com/#!15/6457a/4