SQL查询以从组中获取JSONB中的冲突值

时间:2018-12-11 05:07:15

标签: sql postgresql jsonb

我有一张与以下表格相似的表格。 location_id是另一个表的FK。报告以N + 1的方式保存:在一个位置上,可以使用N个报告者,并且如果可以的话,可以使用一个报告作为事实来源。记者的举报使用一个单字母代码(假设为R),真相来源则使用不同的代码(假设为T)。 JSONB列的键是常规字符串,值是字符串,整数和整数数组的任意组合。

create table report (
  id integer not null primary key,
  location_id integer not null,
  report_type char(1),
  data jsonb
)

鉴于以上所有信息,如何获得所有位置ID,其中给定键集(在查询时提供)的data值与report_type {{ 1}}?

1 个答案:

答案 0 :(得分:1)

至少有两种可靠的方法,这取决于要获得的复杂程度以及密钥的数量和/或动态程度。第一个非常简单:

select location_id
from report
where report_type = 'R'
group by location_id
having count(distinct data->'key1') > 1 
  or count(distinct data->'key2') > 1
  or count(distinct data->'key3') > 1

第二种结构更复杂,但是具有提供非常简单的键列表的优点:

--note that we also need distinct on location id to return one row per location
select distinct on(location_id) location_id
 --jsonb_each returns the key, value pairs with value in type JSON (or JSONB) so the value field can handle integers, text, arrays, etc 
from report, jsonb_each(data)
where report_type = 'R'
 and key in('key1', 'key2', 'key3')
group by location_id, key
having count(distinct value) > 1
order by location_id