PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Postgres jsonb recherche dans un tableau avec un opérateur supérieur (avec jsonb_array_elements)

Au lieu de cross join lateral utiliser 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;

Mettre à jour

Et encore une autre méthode, plus complexe mais aussi beaucoup plus efficace.

Créer une fonction qui renvoie la valeur maximale de votre JSONB données, comme ceci :

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 $$

Créer un index sur cette fonction :

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

Utilisez la fonction dans votre requête :

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

Dans ce cas, l'index sera utilisé et la requête sera beaucoup plus rapide sur une grande quantité de données.

PS :Généralement limit avoir un sens en paire avec order by .