std::vector
является несоответствующим контейнером. Чтобы оптимизировать пространство, он упаковывает bool
s и не может предоставить ссылку.
Вместо этого используйте boost::dynamic_bitset
.
Ответ @a_horse_with_no_name
дает мне хорошее начало. Я расширяю его / ее ответ и подхожу к следующему запросу так, чтобы элементы в массиве JSON имели тот же тип данных, который определен в PostgreSQL.
select id, jsonb_object_agg(att,
case
when strval is not null then strval
when intvalue is not null then intvalue
else boolVal
end
)
from (
select id,
attributename as att,
case when count(*) > 1 then
jsonb_agg(stringvalue) filter (where stringvalue is not null)
else
to_jsonb(min(stringvalue) filter (where stringvalue is not null))
end as strVal,
case when count(*) > 1 then
jsonb_agg(intvalue) filter (where intvalue is not null)
else
to_jsonb(min(intvalue) filter (where intvalue is not null))
end as intvalue,
case when count(*) > 1 then
jsonb_agg(booleanvalue) filter (where booleanvalue is not null)
else
to_jsonb(bool_and(booleanvalue) filter (where booleanvalue is not null))
end as boolVal
from eav
group by id, attributename
) t
group by id;
Вы можете сделать что-то вроде этого:
select id, jsonb_object_agg(att, value)
from (
select id,
attributename as att,
case
when count(*) > 1 then
jsonb_agg(coalesce(stringvalue,intvalue::text,booleanvalue::text))
else
to_jsonb(min(coalesce(stringvalue,intvalue::text,booleanvalue::text)))
end as value
from eav
group by id, attributename
) t
group by id;
Внутренний выбор объединяет несколько значений в массив JSON, отдельные значения в скалярные значения JSON. И тогда внешний запрос строит единственное значение JSON из всех строк.
Онлайн пример: https://rextester.com/TLCRN79815