Postgres:Select 对象数组中值 >= x 且没有值大于 x 的所有行
Postgres: Select all rows from array of objects where value >= x and also where no values are greater than x
我有一个 table 看起来像这样:
sentence data
good [{"pred": "yes", 'prob': 0.6}, {"pred": "maybe", "prob": 0.4}, {"pred": "another", "prob": 0.7}]
bad [{"pred": "unexpected", "prob": 0.4}, {"pred": "uncool", "prob": 0.3}]
我想输出 sentence
的所有 preds
,其中有 prob >= 0.5
。但是,如果一个句子没有 probs
大于 0.5
那么我也想将其包含在结果中。
例如,对于这个数据,结果应该是:
结果:
sentence | preds
-----------+-------
good | ['yes', 'another']
bad | null
(2 rows)
我这样做适用于第一种情况(选择 preds
和 prob >= 0.5
)。但是,我无法选择 probs
不大于 0.5
的句子
SELECT sentence, jsonb_agg(data->'pred') AS preds
FROM table
CROSS JOIN jsonb_array_elements(table.data) AS data
WHERE data->>'prob' >= '0.5'
GROUP BY sentence
尝试 left join lateral
:
# with invars (sentence, data) as (
values
('good', '[{"pred": "yes", "prob": 0.6}, {"pred": "maybe", "prob": 0.4}, {"pred": "another", "prob": 0.7}]'::jsonb),
('bad', '[{"pred": "unexpected", "prob": 0.4}, {"pred": "uncool", "prob": 0.3}]')
)
select sentence, jsonb_agg(d.data) as preds
from invars
left join lateral jsonb_array_elements(data) as d(data)
on (d.data->>'prob')::numeric >= .5
group by sentence;
┌──────────┬──────────────────────────────────────────────────────────────────┐
│ sentence │ jsonb_agg │
├──────────┼──────────────────────────────────────────────────────────────────┤
│ bad │ [null] │
│ good │ [{"pred": "yes", "prob": 0.6}, {"pred": "another", "prob": 0.7}] │
└──────────┴──────────────────────────────────────────────────────────────────┘
(2 rows)
如果您使用的是 Postgres 12 或更高版本,您可以使用 JSON 路径查询:
select sentence,
jsonb_path_query_array(data, '$[*] ? (@.prob >= 0.5).pred') as preds
from the_table;
这将 return 一个空数组 []
对于那些没有任何项目匹配条件的数组。
对于早期版本,我会使用:
select t.sentence,
(select jsonb_agg(e.item -> 'pred')
from jsonb_array_elements(t.data) as e(item)
where (e.item ->> 'prob')::float >= 0.5) as preds
from the_table t;
这 returns null
对于那些没有元素匹配的
我有一个 table 看起来像这样:
sentence data
good [{"pred": "yes", 'prob': 0.6}, {"pred": "maybe", "prob": 0.4}, {"pred": "another", "prob": 0.7}]
bad [{"pred": "unexpected", "prob": 0.4}, {"pred": "uncool", "prob": 0.3}]
我想输出 sentence
的所有 preds
,其中有 prob >= 0.5
。但是,如果一个句子没有 probs
大于 0.5
那么我也想将其包含在结果中。
例如,对于这个数据,结果应该是:
结果:
sentence | preds
-----------+-------
good | ['yes', 'another']
bad | null
(2 rows)
我这样做适用于第一种情况(选择 preds
和 prob >= 0.5
)。但是,我无法选择 probs
不大于 0.5
SELECT sentence, jsonb_agg(data->'pred') AS preds
FROM table
CROSS JOIN jsonb_array_elements(table.data) AS data
WHERE data->>'prob' >= '0.5'
GROUP BY sentence
尝试 left join lateral
:
# with invars (sentence, data) as (
values
('good', '[{"pred": "yes", "prob": 0.6}, {"pred": "maybe", "prob": 0.4}, {"pred": "another", "prob": 0.7}]'::jsonb),
('bad', '[{"pred": "unexpected", "prob": 0.4}, {"pred": "uncool", "prob": 0.3}]')
)
select sentence, jsonb_agg(d.data) as preds
from invars
left join lateral jsonb_array_elements(data) as d(data)
on (d.data->>'prob')::numeric >= .5
group by sentence;
┌──────────┬──────────────────────────────────────────────────────────────────┐
│ sentence │ jsonb_agg │
├──────────┼──────────────────────────────────────────────────────────────────┤
│ bad │ [null] │
│ good │ [{"pred": "yes", "prob": 0.6}, {"pred": "another", "prob": 0.7}] │
└──────────┴──────────────────────────────────────────────────────────────────┘
(2 rows)
如果您使用的是 Postgres 12 或更高版本,您可以使用 JSON 路径查询:
select sentence,
jsonb_path_query_array(data, '$[*] ? (@.prob >= 0.5).pred') as preds
from the_table;
这将 return 一个空数组 []
对于那些没有任何项目匹配条件的数组。
对于早期版本,我会使用:
select t.sentence,
(select jsonb_agg(e.item -> 'pred')
from jsonb_array_elements(t.data) as e(item)
where (e.item ->> 'prob')::float >= 0.5) as preds
from the_table t;
这 returns null
对于那些没有元素匹配的