如何将 postgresql any 与 jsonb 数据一起使用
How to use postgresql any with jsonb data
相关
参见问题
问题
我有一个 postgresql table,其中有一列类型为 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 A
或 Insurance 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[]);
但这 returns 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);
employees->'employment'->'benefits'
是一个 json 数组,因此您应该取消嵌套它以在 any
比较中使用它的元素。
使用函数 jsonb_array_elements_text()
in 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 can also precede a function-call FROM item, but in this case
it is a noise word, because the function expression can refer to
earlier FROM items in any case.
另请参阅:
语法
from jsonb_array_elements_text(employees->'employment'->'benefits') benefits(benefit)
是别名的一种形式,根据 the documentation
Another form of table aliasing gives temporary names to the columns of
the table, as well as the table itself:
FROM table_reference [AS] alias ( column1 [, column2 [, ...]] )
您可以使用包含运算符 ?|
来检查数组是否包含您想要的任何值。
select * from employees
where employees->'employment'->'benefits' ?| array['Insurance A', 'Insurance B']
如果您碰巧希望所有值都在数组中,那么可以使用 ?&
运算符进行检查。
相关
参见
问题
我有一个 postgresql table,其中有一列类型为 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 A
或 Insurance 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[]);
但这 returns 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);
employees->'employment'->'benefits'
是一个 json 数组,因此您应该取消嵌套它以在 any
比较中使用它的元素。
使用函数 jsonb_array_elements_text()
in 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 can also precede a function-call FROM item, but in this case it is a noise word, because the function expression can refer to earlier FROM items in any case.
另请参阅:
语法
from jsonb_array_elements_text(employees->'employment'->'benefits') benefits(benefit)
是别名的一种形式,根据 the documentation
Another form of table aliasing gives temporary names to the columns of the table, as well as the table itself:
FROM table_reference [AS] alias ( column1 [, column2 [, ...]] )
您可以使用包含运算符 ?|
来检查数组是否包含您想要的任何值。
select * from employees
where employees->'employment'->'benefits' ?| array['Insurance A', 'Insurance B']
如果您碰巧希望所有值都在数组中,那么可以使用 ?&
运算符进行检查。