为简单起见,我将在表中写入最少数量的字段。 假设我有这个表:items,item_photos,item_characteristics。
create table items (
id bigserial primary key,
title jsonb not null,
);
create table item_photos (
id bigserial primary key,
path varchar(1000) not null,
item_id bigint references items (id) not null,
sort_order smallint not null,
unique (path, item_id)
);
create table items_characteristics (
item_id bigint references items (id),
characteristic_id bigint references characteristics (id),
characteristic_option_id bigint references characteristic_options (id),
numeric_value numeric(19, 2),
primary key (item_id, characteristic_id),
unique (item_id, characteristic_id, characteristic_option_id));
我想汇总一项的所有照片和特征。 首先,我明白了。
select i.id as id,
i.title as title,
array_agg( ip.path) as photos,
array_agg(
array [ico.characteristic_id, ico.characteristic_option_id, ico.numeric_value]) as characteristics_array
FROM items i
LEFT JOIN item_photos ip on i.id = ip.item_id
LEFT JOIN items_characteristics ico on ico.item_id = i.id
GROUP BY i.id
这里的第一个问题是,如果item_characteristics中有4个与一个项目相关的条目,例如,item_photos没有条目,我将在photos字段{{ 1}}。 所以我不得不使用array_remove:
{null, null, null, null}
此外,如果我有1张照片和4张特征,则会得到4张照片的重复副本,例如:array_remove(array_agg(ip.path), null) as photos
所以我不得不使用不同的:
{img/test-img-1.png,img/test-img-1.png,img/test-img-1.png,img/test-img-1.png}
对我来说,这个决定很尴尬。 我不得不在item_characteristics中再添加2个字段,这使情况变得复杂:
array_remove(array_agg(distinct ip.path), null) as photos,
array_agg(distinct
array [ico.characteristic_id, ico.characteristic_option_id, ico.numeric_value]) as characteristics_array
所以我需要从item_characteristics中聚合5个值,其中2个已经是jsonb并且与众不同可能会对性能产生非常负面的影响。 还有更优雅的解决方案吗?
答案 0 :(得分:1)
加入之前:
SELECT i.id as id, i.title as title, ip.paths, null as photos,
ico.characteristics_array
FROM items i LEFT JOIN
(SELECT ip.item_id, array_agg( ip.path) as paths
FROM item_photos ip
GROUP BY ip.item_ID
) ip
ON ip.id = i.item_id LEFT JOIN
(SELECT ico.item_id,
array_agg(array [ico.characteristic_id, ico.characteristic_option_id, ico.numeric_value]
) as characteristics_array
FROM items_characteristics ico
GROUP BY ico.item_id
) ico
ON ico.item_id = i.id