我有一张与以下表格相似的表格。 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}}?
答案 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