Это ужасный дизайн , и что бы вы ни делали, оно не будет быстрым, особенно с ожидаемым количеством строк, а обслуживание будет кошмаром и ошибкой склонный. Лучше всего сделать редизайн, чтобы получить 1 стол. Поскольку я понятия не имею, для чего служит таблица функций custom_tables, я просто использую остальные. Таким образом, только с двумя другими у вас будет:
create table custom_tables (
id bigserial
, entity_id text -- or integer/bigint if appropriate
, name text
, age integer
) ;
Если вы останетесь с этим (бессмысленным) дизайном, то, по крайней мере, создайте представление, которое по существу отображается в приведенную выше таблицу; или лучше материализованное представление следующим образом:
create or replace view custom_tables_set as
with id_fld as
( select cfv.entity_id, cfv.value id
from custom_field_values cfv
left join custom_fields cf on(cf.id = cfv.custom_field_id)
where cf.alias = 'id'
)
, name_fld as
( select cfv.entity_id, cfv.value as name
from custom_field_values cfv
left join custom_fields cf on(cf.id = cfv.custom_field_id)
where cf.alias = 'name'
)
, age_fld as ( select cfv.entity_id, cfv.value age
from custom_field_values cfv
left join custom_fields cf on(cf.id = cfv.custom_field_id)
where cf.alias = 'age'
)
select i.entity_id, i.id, n.name, a .age
from id_fld i
left join name_fld n on n.entity_id = i.entity_id
left join age_fld a on a.entity_id = i.entity_id ;
Вам нужно будет добавить другое .._fld CTE для каждого создаваемого вами значения псевдонима.
По крайней мере, с представлением вы не будете присоединяться к каждому написанному запросу.
Удачи!