我在mu PostgreSQL 9.05上有这些表:
表:core
字段:name
,description
,data
data
字段是一个json字段,(例如):{"id": "100", "tax": "4,5"}
每个数据始终为one
json。
我的问题是:我可以将所有JSON字段作为查询字段吗?像这样返回:name, description, id, tax....
问题是:我的JSON确实有各种字段,可以是Id,tax或其他。
答案 0 :(得分:8)
你不能“动态地”做到这一点。您需要指定要包含的列:
in
如果你做了很多,你可能想把它放到一个视图中。
另一种选择是在Postgres中创建一个表示JSON中属性的对象类型,例如:
>>> all(e in s for e in ('24','England'))
True
>>> any(e in s for e in ('France','England'))
True
>>> all(e in s for e in ('France','England'))
False
然后,您可以将JSON强制转换为该类型,并且JSON中的相应属性将自动转换为列:
使用上述类型和以下JSON:select name, description, id,
data ->> 'tax' as tax,
data ->> 'other_attribute' as other_attribute
from core;
,您可以执行以下操作:
create type core_type as (id integer, tax numeric, price numeric, code varchar);
它会返回:
{"id": "100", "tax": "4.5", "price": "10", "code": "YXCV"}
但是你需要确保每个JSON值都可以转换为相应对象字段的类型。
如果更改对象类型,则会自动更新使用它的任何查询。因此,您可以通过中央定义管理您感兴趣的列。
答案 1 :(得分:4)
从PostgreSQL 9.4开始,您也可以使用json_to_record
。
从JSON对象构建任意记录(请参阅下面的注释)。与返回记录的所有函数一样,调用者必须使用AS子句显式定义记录的结构。
例如:
a | b | d
---+---------+---
1 | [1,2,3] |
返回
{{1}}
答案 2 :(得分:0)
我觉得很烦人,没有人找到合适的解决方案。
将 OP 问题解读为:“给定一个具有 JSON 字段的表,具有不同的键,并且没有预先知道这些键的存在或身份,我如何将这些值作为统一记录集的一部分获取?”
>理想情况下,解决方案将在单个脚本中完成此操作,可用作应用程序的视图或源,但以下内容在存储过程中很有用,或者如果您的 JSON 架构很少更改。
select
concat_ws(
' ',
e'select\n\t*,',
string_agg(
distinct concat(
e'\tcase ',e'json_field?\'', json_column_key, e'\'\n\t\t',
e'when true then json_field->\'', json_column_key,e'\'\n\t\t',
e'else NULL\n\t',
'end as ',json_column_key,
),
e',\n\t'
),
e'\nfrom table_with_json'
) as generated_sql_script
from (
select json_object_keys(annotations) as json_column_key
from table_with_json.answers
where json_typeof(json_field) like 'object'
) as generate_promoted_json
输出是一个记录集,描述父表中的所有列,包括具有 json 对象的列,但每个属性都有单独的列,这些列可能存在也可能不存在于特定记录中。
一些不足:
除此之外,它应该是一个通用的实用程序。