cross join lateral
の代わりに 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;
更新
さらに別の方法で、より複雑ですが、はるかに効率的です。
JSONB
から最大値を返す関数を作成します このようなデータ:
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 $$
この関数のインデックスを作成します:
create index idx_max_PAYABLE_INVOICE_LINES_value
on documents(fn_get_max_PAYABLE_INVOICE_LINES_value(data_block));
クエリで関数を使用する:
select *
from documents d
where fn_get_max_PAYABLE_INVOICE_LINES_value(data_block) > 1000
limit 50;
この場合、インデックスが使用され、大量のデータに対してクエリがはるかに高速になります。
PS:通常はlimit
order by
と組み合わせて意味を持ちます 。