SELECT company
, CASE WHEN sum(amount) >= 500
THEN json_agg(json_build_object(account, amount))
ELSE json_agg(json_build_object(account, amount)) FILTER (WHERE amount_rn = 1) END AS json_array
, CASE WHEN sum(amount) >= 500
THEN array_agg((account, amount))
ELSE array_agg((account, amount)) FILTER (WHERE amount_rn = 1) END AS plain_array
, CASE WHEN sum(amount) >= 500 THEN 'Met' ELSE 'Failed' END AS status
FROM (
SELECT *
, sum(amount) OVER (PARTITION BY company ORDER BY id ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) AS running_sum
, row_number() OVER (PARTITION BY company ORDER BY amount DESC NULLS LAST, id) AS amount_rn
FROM tbl
ORDER BY company, id
) sub
WHERE running_sum >= 500 IS NOT TRUE
GROUP BY 1;