Sql 如何在Postgres中对json数据进行计算

Sql 如何在Postgres中对json数据进行计算,sql,json,postgresql,jsonb,Sql,Json,Postgresql,Jsonb,我正在Postgres中存储AdWords报告数据。每个报表都存储在名为Reports的表中,该表有一个名为“data”的jsonb列。每个报表的“数据”字段中都存储有json,如下所示: [ { match_type: "exact", search_query: "gm hubcaps", conversions: 2, cost: 1.24 }, { match_type: "broad", search_query: "gm a

我正在Postgres中存储AdWords报告数据。每个报表都存储在名为Reports的表中,该表有一个名为“data”的jsonb列。每个报表的“数据”字段中都存储有json,如下所示:

[
  {
    match_type: "exact",
    search_query: "gm hubcaps",
    conversions: 2,
    cost: 1.24
  },
  {
    match_type: "broad",
    search_query: "gm auto parts",
    conversions: 34,
    cost: 21.33
  },
  {
    match_type: "phrase",
    search_query: "silverdo headlights",
    conversions: 63,
    cost: 244.05
  }
]
我要做的是查询这些数据散列,并汇总给定报表的转换总数。我看过Postgresql文档,看起来你只能对散列进行计算,而不是像这样的散列数组。我想在博士后做的事可能吗?我是否需要用这个数组制作一个临时表并进行计算?或者我可以使用存储过程吗

我正在使用Postgresql 9.4

编辑 我之所以不使用常规的、规范化的表,是因为这只是报表数据结构的一个示例。在我的项目中,报告必须允许任意键,因为它们是由用户使用他们喜欢的任何列上传CSV来填充的。这基本上只是一种绕过任意多个用户创建的表的方法。

您可以使用unnest:

免责声明:我没有第9.2页,所以我不能自己测试

编辑:这是假设您提到的数组是Postgresql数组,即数据列的数据类型是字符变化[]。如果您的意思是数据是一个json数组,那么您应该能够使用json_数组_元素而不是unnest

我要做的是查询这些数据散列并汇总转换

最快的方法应该是使用。但您需要为其注册行类型

创建临时表报告\u数据 -匹配类型文本-注释掉,因为我们只需要。。 -,搜索\查询文本-。。此查询的转换 整数转换 -,成本数字 ; 临时表是临时注册行类型的一种方法。在这个相关的回答中有更多的解释:

由于缺少信息,假设报表id为PK的表报表

选择r.report\u id、sumd.conversions作为sum\u转换 来自报告r 左连接横向jsonb_填充_记录集NULL::报告_数据,r.d数据为真 -其中r.report_id=12345-仅适用于给定报告? 分组1例; 左连接确保获得结果,即使数据为NULL或空,或者JSON数组为空

对于基础表中单个行的总和,这会更快:

选择d.sum\u转换 来自报告r 左外侧连接 选择sumconversions作为sum\u转换 从jsonb_填充_记录集null::报告_数据,r.data 真的吗 其中r.report_id=12345;-在此处输入报告id 不需要注册行类型的备选方案:

选择d.sum\u转换 来自报告r 左外侧连接 选择sumvalue->>“转换”::int作为sum\u转换 来自jsonb_数组_元素sr.data 真的吗 其中r.report_id=12345;-在此处输入报告id
通常,您会将其实现为普通的、规范化的表。我看不到JSON的好处,除了您的应用程序似乎需要它,就像您添加的那样。

也许您应该将它变成一个永久表,由于此结构正好适合关系模型,并且将其保存在JSON中意味着每个查询都将变得更复杂、效率更低。psql中的表定义\d tbl和您的Postgres版本对于此问题至关重要。另外:每个报表或总体?unnest的总和约定只能应用于Postgres数组。不是JSON或jsonb类型内的JSON数组。该数组实际上是jsonb类型。我将尝试json_数组_元素。我听到了关于规范化的内容。我之所以采用这种方法,是因为项目要求用户可以上传任何csv文档,无论其结构如何以及其中包含哪些列。我只是以这个AdWords报告为例。同时,感谢您指出缺乏细节。我将编辑这个问题。
select sum(conv) from
(select d->'conversion' as conv from
(select unnest(data) as d from <your table>) all_data
) all_conv