如何使用postgresql任何jsonb数据

时间:2016-07-12 09:03:12

标签: postgresql jsonb

相关

请参阅this问题

问题

我有一个postgresql表,其中包含一个jsonb类型的列。 json数据看起来像这样

{
   "personal":{
      "gender":"male",
      "contact":{
         "home":{
            "email":"ceo@home.me",
            "phone_number":"5551234"
         },
         "work":{
            "email":"ceo@work.id",
            "phone_number":"5551111"
         }
      },
      ..
      "nationality":"Martian",
      ..
   },
   "employment":{
      "title":"Chief Executive Officer",
      "benefits":[
         "Insurance A",
         "Company Car"
      ],
      ..
   }
}

此查询效果非常好

select employees->'personal'->'contact'->'work'->>'email' 
from employees 
where employees->'personal'->>'nationality' in ('Martian','Terran')

我想抓取所有有Insurance AInsurance B类型好处的员工,这个丑陋的查询有效:

 select employees->'personal'->'contact'->'work'->>'email' 
   from employees 
   where employees->'employment'->'benefits' ? 'Insurance A' 
   OR employees->'employment'->'benefits' ? 'Insurance B';

我想使用any代替:

select * from employees 
where employees->'employment'->>'benefits' = 
any('{Insurance A, Insurance B}'::text[]);

但这会返回0结果..想法?

我还尝试了什么

我尝试了以下语法(全部失败):

.. = any({'Insurance A','Insurance B'}::text[]);
.. = any('Insurance A'::text,'Insurance B'::text}::array);
.. = any({'Insurance A'::text,'Insurance B'::text}::array);
.. = any(['Insurance A'::text,'Insurance B'::text]::array);

2 个答案:

答案 0 :(得分:2)

employees->'employment'->'benefits'是一个json数组,所以你应该在any比较中使用它的元素。 使用jsonb_array_elements_text()中的lateral join功能:

select *
from 
    employees, 
    jsonb_array_elements_text(employees->'employment'->'benefits') benefits(benefit)
where
    benefit = any('{Insurance A, Insurance B}'::text[]);

语法

from 
    employees, 
    jsonb_array_elements_text(employees->'employment'->'benefits')

相当于

from 
    employees, 
    lateral jsonb_array_elements_text(employees->'employment'->'benefits')

可以省略单词lateral。对于the documentation

  

LATERAL也可以在函数调用FROM项之前,但在这种情况下   它是一个干扰词,因为函数表达式可以参考   在任何情况下早于FROM项目。

另请参阅:What is the difference between LATERAL and a subquery in PostgreSQL?

语法

from jsonb_array_elements_text(employees->'employment'->'benefits') benefits(benefit)

是一种别名形式,每the documentation

  

另一种形式的表别名为列提供临时名称   表格,以及表格本身:

     

FROM table_reference [AS]别名(column1 [,column2 [,...]])

答案 1 :(得分:1)

您可以使用包含运算符?|来检查数组是否包含您想要的任何值。

select * from employees 
where employees->'employment'->'benefits' ?| array['Insurance A', 'Insurance B']

如果您遇到了希望所有值都在数组中的情况,那么可以使用?&运算符来检查它。