【问题标题】:How to correctly use COUNT() when multiple joins are used?使用多个联接时如何正确使用 COUNT()?
【发布时间】:2021-01-28 13:31:32
【问题描述】:

我有以下架构:

多个webinar 实体可以有多个categories 因此webinarcategorymapping 表。

我需要实现的是找到特定category 中最受欢迎的webinars(按赞数)。

为此,我编写了以下查询:

select
    webinar.id, webinar.name as "webinar", webinar.publishat,
    string_agg(category.name, ',' order by category.name) as categories,
    count("like".likeableid) as "likes_count"
    from
        webinar
        join "like" on webinar.id = "like".likeableid and "like".likeabletype = 'webinar'
        join webinarcategorymapping on webinarcategorymapping.webinarid = webinar.id
        join category on category.id = webinarcategorymapping.categoryid
    group by "like".likeableid, webinar.id
    having
        string_agg(category.name, ',' order by category.name) ilike '%CategoryName%'
        and count("like".likeableid) > 0
    order by count("like".likeableid) desc;

由于categorywebinar 之间的多对多关系,我决定使用string_agg 将每个webinar 的所有类别连接成一个逗号分隔值。这样我就可以使用ilike %search_term%按类别进行搜索。

like 表中,likeabletype 必须等于webinarlikeableid 字段是进行类似操作的实体的 ID。因此,就我而言,在查询like 表时,我需要使用likeabletype='webinar'likeableid = webinar.id 条件。

问题是给了我不正确的likes_count 结果(我猜这是由于多个连接重复了许多行)。

但是,使用 count(distinct "like".likeableid) 并没有帮助,因为它只会为每一行提供 1


为了从count()likes 获得正确的结果,我应该在我的查询中进行哪些更改?

【问题讨论】:

  • 您可以在加入之前在子查询中进行 GROUP BY。
  • 不清楚likes 是如何连接到其他表的。另外,您关心的具体类别是什么?

标签: sql postgresql join


【解决方案1】:

我需要实现的是找到特定类别中最受欢迎的网络研讨会(按赞数)。

您可以在子查询中聚合 likes 并仅过滤类别:

select w.id, w.name as "webinar", w.publishat, num_likes
from webinar w join
     (select l.likableid, count(*) as num_likes
      from "like" l
      where l.likeabletype = 'webinar'
      group by l.likeableid
     ) l
     on w.id = l.likeableid join
     webinarcategorymapping wcm
     on wcm.webinarid = w.id join
     category c
     on c.id = wcm.categoryid
where c.name = ?
order by num_likes desc;

【讨论】:

  • 您的查询工作正常,但给了我重复的行。如果我在第一个select 之后添加distinct,它就可以正常工作。在这里使用distinct 是否是实现所需结果的正确方法?
  • @DenisYakovenko 。 . .我怀疑重复的行是由与网络研讨会匹配的多个类别引起的。您可以将使用 where exists 的类别比较替换为相关子查询。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多