我的参加者表有一个jsonb
名为eventfilters
.
给定与 具有相同签名(表单)的查询过滤器数组eventfilters
,我需要eventfilters
通过查询过滤器值选择针对该字段过滤的与会者。
以下是查询过滤器和eventfilters
字段的示例:
该eventfilters
字段如下所示:
[
{
"field": "Org Type",
"selected": ["B2C", "Both", "Nonprofit"]
},
{
"field": "Job Role",
"selected": ["Customer Experience", "Digital Marketing"]
},
{
"field": "Industry Sector",
"selected": ["Advertising", "Construction / Development"]
}
]
查询过滤器可能如下所示:
[
{
"field": "Org Type",
"selected": ["B2C", "Nonprofit"]
},
{
"field": "Industry Sector",
"selected": ["Advertising"]
}
]
因此,eventfilters
字段和查询过滤器始终具有相同的签名:
Array<{"field": text, "selected": text[]}>
给定查询过滤器和eventfilters
上面的过滤逻辑,过滤逻辑如下:
- 选择具有以下
eventfilters
字段的所有与会者:selected
带有field: "Org Type"
参加者 ( )的数组eventfilters
包含数组中存在的任何值,该selected
数组带有查询过滤器的“组织类型”字段; 和selected
带有field: "Industry Sector"
参加者 ( )的数组eventfilters
包含数组中存在的任何值,该selected
数组带有查询过滤器的“行业部门”字段。
查询过滤器数组可以有不同的长度和不同的元素,但总是具有相同的签名(形式)。
我能想出的是上述逻辑,但不是and
查询过滤器中的每个元素,而是or
:
select distinct attendee.id,
attendee.email,
attendee.eventfilters
from attendee cross join lateral jsonb_array_elements(attendee.eventfilters) single_filter
where (
((single_filter ->> 'field')::text = 'Org Type' and (single_filter ->> 'selected')::jsonb ?| array ['B2C', 'Nonprofit'])
or ((single_filter ->> 'field')::text = 'Industry Sector' and (single_filter ->> 'selected')::jsonb ?| array ['Advertising'])
);
基本上我需要将上述查询or
中的where
子句更改为and
,但这显然行不通。
该where
子句将动态生成。
这是我现在如何生成它的示例(它是 javascript,但我希望你能掌握这个想法):
function buildEventFiltersWhereSql(eventFilters) {
return eventFilters.map((filter) => {
const selectedArray = filter.selected.map((s) => `'${s}'`).join(', ');
return `((single_filter ->> 'field')::text = '${filter.field}' and (single_filter ->> 'selected')::jsonb ?| array[${selectedArray}])`;
}).join('\nor ');
}
or
和and
逻辑的简单交换在实现中似乎非常不同。我想使用 来实现它会更容易jsonpath
,但我的 postgres 版本是 11 :(
我怎样才能实现这样的过滤?
PS:create table
和insert
复制代码:https ://pastebin.com/1tsHyJV0