【问题标题】:Postgres: averaging a column on distinct of another column in already grouped queryPostgres:在已分组查询中对另一列的不同列进行平均
【发布时间】:2017-04-04 19:01:00
【问题描述】:

当查询已经为其他目的分组而不使用子查询时,是否有办法仅在另一列的不同列上平均列?我知道这可以通过子查询来完成,但除非绝对必要,否则尽量避免重组旧查询。

现有查询虽然复杂,但与以下示例具有或多或少相同的结构。如您所见,图书馆有任意数量的书籍,一本书有任意数量的章节,一章有任意数量的段落,而查询返回每个图书馆的书籍和段落总数。

SELECT libraries.name,
 COUNT(DISTINCT books.id) AS num_books,
 COUNT(paragraphs.id) AS num_paragraphs
FROM libraries
LEFT JOIN books ON books.library_id = libraries.id
LEFT JOIN chapters ON chapters.book_id = books.id
LEFT JOIN paragraphs ON paragraphs.chapter_id = chapters.id
GROUP BY libraries.name

现在假设表 books 有一个列 publish_year,我想要图书馆的平均出版年份。显然我不能简单地添加 AVERAGE(books.publish_year),因为包含更多章节和段落的书籍会影响平均值。

有没有一种很好的方法可以根据不同的 books.id 再次对 books.publish_year 进行平均,而无需重新构建查询或重新构建查询?

【问题讨论】:

    标签: postgresql aggregate


    【解决方案1】:

    加入前的窗口函数

    select
        l.name,
        count(distinct b.id) as num_books,
        count(p.id) as num_paragraphs,
        min(year_avg) as year_avg
    from
        libraries l
        left join (
            select *, avg(publish_year) over(partition by library_id) as year_avg
            from books
        ) b on b.library_id = l.id
        left join chapters c on c.book_id = b.id
        left join paragraphs p on p.chapter_id = c.id
    group by l.name
    

    【讨论】:

    • 哦,好吧,我明白你在做什么了。这应该适用于我的示例,其中 libraries 是主表。如果 books 是主表并且 libraries 保持连接状态,如何应用这种方法?
    • @IanBui 这是您发布的问题的答案,而不是您未发布的问题的答案。在发帖和浪费他人时间之前,请先下定决心。
    • 嗯,它们是相关的。我没有意识到提出后续问题会被视为“浪费”您的时间。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-12
    • 2016-06-05
    • 1970-01-01
    • 1970-01-01
    • 2016-06-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多