如何解决postgres一对多扁平化收益
我正在尝试编写一个使用3个表的postgres查询:people,attribute和people_attribute联接
人物表:
id,name
属性表:
id,name,attr_group
people_attribute加入:
people_id,attribute_id
所需的输出:
name | fav_colors | fav_music | fav_foods
-----------------------------------------------------------------
michael | red,blue,green | pop,hip-hop,jazz | pizza,burgers,tacos
bob | orange,green | null | tacos,steak,fish
...等
每个attr_group的标签范围从无到〜12
这是我正在使用的查询:
select
p.id,p.name,(case when a.attr_group like 'fav_colors' then string_agg(a.name,',') else null end) as fav_colors,(case when a.attr_group like 'fav_music' then string_agg(a.name,') else null end) as fav_music,(case when a.attr_group like 'fav_foods' then string_agg(a.name,') else null end) as fav_foods,from people as p
join people_attribute as pa on pa.people_id = p.id
join "attribute" as a on a.id = pa.attribute_id
group by 1,2,a.attr_group
order by 1 asc;
返回:
name | fav_colors | fav_music | fav_foods
-----------------------------------------------------------------
michael | red,green | null | null
michael | null | pop,jazz | null
michael | null | null | pizza,tacos
bob | null | null | null
bob | orange,green | null | null
bob | null | null | tacos,fish
我感觉自己接近了,但是不确定如何将其展平以实现所需的输出,如上所示。任何帮助将不胜感激!
解决方法
您要为此使用filter
:
select p.id,p.name,string_agg(a.name,',') filter (where a.attr_group = 'fav_color') as fav_colors,') filter (where a.attr_group = 'fav_music') as fav_music,') filter (where a.attr_group = 'fav_foods') as fav_foods,from people as p
join people_attribute as pa
on pa.people_id = p.id
join "attribute" as a
on a.id = pa.attribute_id
group by p.id,p.name
order by 1 asc;
使用filter
仅将符合filter
where
条件的值传递到聚合中。
您的每个people
记录显示三行的原因是因为您在attribute.attr_group
中添加了group by
。因为您在attribute.attr_group
条件中使用case
,所以别无选择。
使用filter
使attribute.attr_group
成为聚合的一部分,因此您不必将其包括在group by
列表中。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。