简体   繁体   English

Postgres:Select 对象数组中值 >= x 以及没有值大于 x 的所有行

[英]Postgres: Select all rows from array of objects where value >= x and also where no values are greater than x

I have a table that looks like this:我有一个看起来像这样的表:

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}]

I want to output all preds for a sentence that have prob >= 0.5 .我想 output 所有predssentenceprob >= 0.5 However, if a sentence has no probs greater than 0.5 then I want to include that in the result as well.但是,如果一个句子的probs不大于0.5 ,那么我也想将其包含在结果中。

For example, for this data, the result should be:例如,对于这个数据,结果应该是:

Result:结果:


  sentence | preds 
-----------+-------
 good      | ['yes', 'another']
 bad       | null    
(2 rows)

I did this which works for the first case (picking preds with prob >= 0.5 ).我这样做适用于第一种情况(使用prob >= 0.5选择preds )。 However, I am not able to pick the sentences that have no probs greater than 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

If you are using Postgres 12 or later, you can use a JSON path query:如果您使用的是 Postgres 12 或更高版本,则可以使用 JSON 路径查询:

select sentence, 
       jsonb_path_query_array(data, '$[*] ? (@.prob >= 0.5).pred') as preds
from the_table;

This would return an empty array [] for those that don't have any items matching the condition.对于那些没有任何符合条件的项目的人,这将返回一个空数组[]


For earlier versions, I would use:对于早期版本,我会使用:

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;

This returns null for those where no element matches这将为没有元素匹配的那些返回null

Try left join lateral :尝试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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM