PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Postgres-JSONB-Suche im Array mit größerem Operator (mit jsonb_array_elements)

Statt cross join lateral Verwenden Sie 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;

Aktualisieren

Und noch eine Methode, komplexer, aber auch viel effizienter.

Erstellen Sie eine Funktion, die den maximalen Wert aus Ihrem JSONB zurückgibt Daten, etwa so:

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

Index für diese Funktion erstellen:

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

Verwenden Sie die Funktion in Ihrer Abfrage:

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

In diesem Fall wird der Index verwendet und die Abfrage ist bei großen Datenmengen viel schneller.

PS:Normalerweise limit haben Sinn im Paar mit order by .