PostgreSQL 不同并在不同字段上分组

Posted

技术标签:

【中文标题】PostgreSQL 不同并在不同字段上分组【英文标题】:PostgreSQL distinct and group on different fields 【发布时间】:2020-11-16 06:05:01 【问题描述】:

通过以下查询,我可以获得添加到成员资格表中的项目成员列表,并与项目所有者联合(他们可能在成员资格表中没有条目)

select sub.user, sub.project, sub.role, sub.order, sub.name from
(SELECT 
    memberships."user",
    memberships.project,
    memberships.role,
    roles."order",
    roles.name
FROM memberships
    JOIN roles ON roles.id = memberships.role
UNION
    SELECT projects.owner AS "user",
        projects.id AS project,
        1 AS role,
        0 AS "order",
        'admin'::text AS name
    FROM projects
) as sub

上述查询产生以下结果集。

8   2   1   0   "admin"
8   1   3   2   "contributor"       (added through memberships table)
6   1   1   0   "admin"
8   4   1   0   "admin"
8   1   1   0   "admin"             (duplicate because user #8 is the owner of project #1)

现在我想通过获取最少order 的行的内容来删除重复的条目。使用distinct on (sub.order) 不包括所有行

select distinct on (sub.order) * from
-- the same subquery
order by sub.order

以上产量

8   2   1   0   "admin"
8   1   3   2   "contributor"

使用group by sub.user, sub.project 和聚合min(sub.order) 有效,但其他两个字段如rolename 被忽略

select sub.user, sub.project, min(sub.order) from
-- the same subquery
group by sub.user, sub.project

我想要rolenameorderuser, project 对分组时具有最小order 的行

【问题讨论】:

【参考方案1】:

我想要与用户、项目对分组时具有最小顺序的行的角色、名称和顺序

distinct on 必须枚举“分组”列 - 然后order by 子句必须包含相同的列,然后是用于打破联系的列。

你可能想要:

select distinct on (t.user, t.project) * 
from ( 
    -- the same subquery -- 
) t
order by t.user, t.project, t.order

【讨论】:

以上是关于PostgreSQL 不同并在不同字段上分组的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL 选择 r.* by MIN() 并在两列上进行分组

如何在postgresql中设置与id不同的自动增量字段

将源自不同表的两个 postgresql tsvector 字段连接到单个 postgresql 视图中,以启用联合全文搜索

通过其字段的不同值对Realm对象进行分组

按 4 个不同级别和总数字字段分组

如何在 PostgreSQL 中只使用一个字段进行分组?