PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Postgres jsonb ricerca in array con operatore maggiore (con jsonb_array_elements)

Invece di cross join lateral usa where exists :

select *
from documents d
where exists (
  select 1
  from jsonb_array_elements(d.data_block -> 'PAYABLE_INVOICE_LINES') as pil
  where (pil->'AMOUNT'->>'value')::decimal >= 1000)
limit 50;

Aggiorna

E ancora un altro metodo, più complesso ma anche molto più efficiente.

Crea una funzione che restituisca il valore massimo dal tuo JSONB dati, in questo modo:

create function fn_get_max_PAYABLE_INVOICE_LINES_value(JSONB) returns decimal language sql as $$
  select max((pil->'AMOUNT'->>'value')::decimal)
  from jsonb_array_elements($1 -> 'PAYABLE_INVOICE_LINES') as pil $$

Crea un indice su questa funzione:

create index idx_max_PAYABLE_INVOICE_LINES_value
  on documents(fn_get_max_PAYABLE_INVOICE_LINES_value(data_block));

Usa la funzione nella tua query:

select *
from documents d
where fn_get_max_PAYABLE_INVOICE_LINES_value(data_block) > 1000
limit 50;

In questo caso verrà utilizzato l'indice e la query sarà molto più veloce su grandi quantità di dati.

PS:Di solito limit avere senso in coppia con order by .