在 PostgreSQL 12 上按 id(唯一)分组的查询中同时获取房间成员、房间所有者和管理员

Get room members, room's owner and admin at the same time in one query with grouped by id (unique) on PostgreSQL 12

我想获取房间的 member 列表,房间的所有者 member 以防他不存在于其他 table 和管理员 member 同时.目前我单独获取它们。

CREATE TABLE public.room_members (
  id               bigint NOT NULL,
  member_id        bigint,
  room_id       bigint,
  group_id  bigint
);


CREATE TABLE public.rooms (
  id               bigint NOT NULL,
  member_id        bigint,
  group_id  bigint,
   name varchar(128)
);


CREATE TABLE public.members (
  id               bigint NOT NULL,
  group_id  bigint,
  username varchar(128),
    is_admin bool default false
);

CREATE TABLE public.groups (
  id               bigint NOT NULL,
  name varchar(128)
);


-- My Group created
INSERT INTO "groups" (id, name) VALUES (1, 'My Group');

-- Create users for this group. We have 4 users/members
INSERT INTO "members" (id, group_id, username, is_admin) VALUES (1, 1, 'Pratha', true);
INSERT INTO "members" (id, group_id, username) VALUES (2, 1, 'John');
INSERT INTO "members" (id, group_id, username) VALUES (3, 1, 'Mike');
INSERT INTO "members" (id, group_id, username) VALUES (4, 1, 'April');

-- April creates a room and he is owner of this room
INSERT INTO "rooms" (id, group_id, member_id, name) VALUES (1, 1, 4, 'My Room'); -- 4 is April

-- April also adds Mike to the room members. But she does not add herself. As she is owner.
INSERT INTO "room_members" (id, group_id, room_id, member_id) VALUES (1, 1, 1, 3); -- 3 is Mike

我想要的是:

  1. room_members 'My Room' 列表 (目前只有 Mike)
  2. 我的房间的所有者,以防他没有将自己添加到 room_members table。因为他是那个房间的主人(也就是四月)
  3. 另外,管理员成员 (这是 Pratha)

而且这应该是独一无二的。例如,如果用户将自己添加到 room_membersowner,那么它应该只获取成员一次。

到目前为止我尝试了什么?

select * from members
left outer join room_members cm on cm.member_id = members.id
left outer join rooms c on c.id = cm.room_id
where c.name = 'My Room' or members.id = 1

我这里也不能用group by。我也不需要所有领域。仅 room_members table 个字段。

看这里https://rextester.com/XWDS42043

room_members 的预期输出:

+-------------+------------+------------+
|  member_id  |  group_id  |  username  |
+-------------+------------+------------+
|      1      |      1     |   Pratha   |
+-------------+------------+------------+
|      3      |      1     |    Mike    |
+-------------+------------+------------+
|      4      |      1     |    April   |
+-------------+------------+------------+

room_members可以很多。我只添加了 Mike,但它可以有多个成员,包括管理员和所有者。

您可以通过 UNION 来解决这个问题:

-- list the admin(s) of the room group
select m.id, m.group_id, m.username 
from rooms r 
inner join members m on m.group_id = r.group_id and m.is_admin = true
where r.name = 'My Room'
union
-- list the members of the room
select m.id, m.group_id, m.username 
from rooms r 
inner join room_members rm on r.id = rm.room_id
inner join members m on rm.member_id = m.id
where r.name = 'My Room'
union
-- recover the room owner
select m.id, m.group_id, m.username 
from rooms r 
inner join members m on r.member_id = m.id
where r.name = 'My Room'

UNION 消除了跨查询的重复项,因此如果用户同时是成员 and/or 组管理员 and/or 房间的所有者,他们只会出现一次。

在您的 fiddle 中,此查询 returns:

id  group_id    username
1   4   1       April
2   3   1       Mike
3   1   1       Pratha