1つの簡単な解決策は、それを結合に変換することです
select v.id, v.pos, v.time, v.status, vi.name,vi.type,
reg_owner.fullname AS registered_owner,
gr_ben_owner.fullname AS group_beneficial_owner,
op.fullname AS operator,
man.fullname AS manager
from
car_pos v
left join cars vi on v.id = vi.id
left join company reg_owner on vi.registered_owner_code = reg_owner.owcode
left join company gr_ben_owner on vi.group_beneficial_owner_code = gr_ben_owner.owcode
left join company op on vi.operator_code = op.owcode
left join company man on vi.manager_code = man.owcode
where age(now(), v.time::time with time zone) < '1 days'::interval
ただし、テーブル Company の結合を 1 つだけ実行することで可能になるのではないかと思います... への正確な構文について 100% 確信が持てず、これによりパフォーマンスが向上するかどうか疑問があります (すべての CASE- WHEN、GROUP by など) を 4 回の結合ソリューションと比較しましたが、これも機能するはずです。(cars-car_pos は 1 対 1 の関係だと思います)
select v.id, MAX(v.pos) as pos, MAX(v.time) as vtime, MAX(v.status) as status, MAX(vi.name) as name,MAX(vi.type) as type,
MAX(CASE WHEN c.owcode = vi.registered_owner_code THEN c.fullname END) AS registered_owner,
MAX(CASE WHEN c.owcode = vi.group_beneficial_owner_code THEN c.fullname END) AS group_beneficial_owner,
MAX(CASE WHEN c.owcode = vi.operator_code THEN op.fullname END) AS operator,
MAX(CASE WHEN c.owcode = vi.manager_code THEN man.fullname END) AS manager
from
car_pos v
left join cars vi on v.id = vi.id
left join company c on c.owcode IN (vi.registered_owner_code, vi.group_beneficial_owner_code, vi.operator_code, vi.manager_code)
group by v.id
having age(now(), vtime::time with time zone) < '1 days'::interval
テーブル作成DDLスクリプトといくつかの挿入を質問に入れることができれば、SQLフィドルで簡単に試すことができます...