【发布时间】:2020-09-28 01:02:57
【问题描述】:
作为参考,我使用的是 Postgres 9.2.23。
我有几个表,其中一个表 (user_group) 与其他一些表相关(例如:posts、group_invites 和其他一些表)。还有一个 groups 表,但它不包含我在这些查询中需要的任何数据。
表user_group:
fk_user_group_id, fk_user_id, fk_group_id, fk_invite_id user_status, ...
表message:
pk_message_id, fk_user_id, fk_group_id, child_message_id, ...
表group_prospective_user:
pk_prospective_user_id, fk_group_id, ...
我想获取指定组 ID 列表的每个相关表的一些统计信息如果用户是该组的成员。
现在我对每个相关表进行一次查询,例如:
select
"public"."user_group"."fk_group_id" as "groupId",
count(case
when (
"public"."message"."child_message_id" is null
and "public"."message"."pk_message_id" is not null
) then "public"."message"."pk_message_id"
end) as "numDiscussions",
count("public"."message"."pk_message_id") as "numDiscussionPosts"
from "public"."user_group"
left outer join "public"."message"
on "public"."message"."fk_group_id" = "public"."user_group"."fk_group_id"
where (
"public"."user_group"."fk_group_id" in (
1, 11, 23, 530, 1070
)
and "public"."user_group"."role" in (
'ADMINISTRATOR', 'MODERATOR', 'MEMBER'
)
and "public"."user_group"."fk_user_id" = 17517
)
group by "public"."user_group"."fk_group_id"
对于邀请:
select
"public"."user_group"."fk_group_id" as "groupId",
count(case
when "public"."prospective_user"."status" = 1 then "public"."prospective_user"."pk_prospective_user_id"
end) as "numInviteesExternal"
from "public"."user_group"
left outer join "public"."prospective_user"
on "public"."prospective_user"."fk_group_id" = "public"."user_group"."fk_group_id"
where (
"public"."user_group"."fk_group_id" in (
1, 11, 23, 530, 6176
)
and "public"."user_group"."role" in (
'ADMINISTRATOR', 'MODERATOR', 'MEMBER'
)
and "public"."user_group"."fk_user_id" = 17517
)
group by "public"."user_group"."fk_group_id"
统计组邀请数量的查询与上面的查询非常相似。只需更改 count when 和 join on。
对这些表的每个查询都具有相同的相关逻辑,用于检查当前用户所属的组。有没有有效的方法将多个类似的查询合并到一个查询中?
我尝试将多个LEFT JOINs 与select count distinct 一起使用,但这在包含大量消息和大量邀请的群组中遇到了性能问题。有没有办法通过子查询轻松/有效地做到这一点?
【问题讨论】:
-
快速提示:使用表别名并避免重复长的多部分表名。
-
@Parfait 谢谢!我实际上正在使用 JOOQ,所以这一切都是为我自动生成的,但我会记住它以备将来使用。另外,我想如果我在这里这样做会有助于提高可读性,现在我想到了。
-
我认为这看起来像带有所有双引号和多部分标识符的 ORM。由于 SQL 答案可能比用 JOOQ 编写的更复杂,因此请考虑提出
jooq和java问题。 -
我的直接答案是通过组列将两者作为派生表连接起来。很难避免重复计算以合并来自不同数据源的汇总问题。
-
与您的问题无关,但是:Postgres 9.2 是no longer supported,您应该尽快计划升级。
标签: sql postgresql-9.2