SQL 查询以从组中获取 JSONB 中的冲突值
SQL query to get conflicting values in JSONB from a group
我有一个 table 定义类似于下面的。 location_id
是另一个 table 的 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
不完全相同R
?
至少有两种可靠的方法,具体取决于您想要获得的复杂程度以及 and/or 动态键的数量。第一个很直接:
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
我有一个 table 定义类似于下面的。 location_id
是另一个 table 的 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
不完全相同R
?
至少有两种可靠的方法,具体取决于您想要获得的复杂程度以及 and/or 动态键的数量。第一个很直接:
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