为什么此查询需要汇总?

时间:2019-07-01 01:56:54

标签: sql postgresql subquery aggregate

我试图将2个表合并为一个表book(它们具有一对一的关系),然后嵌套一对多的关系ebooks

如果我尝试嵌套一对多结果,则效果很好:

select r.*, array_agg(e) e_books from gardner_record r
left join gardner_e_book_record e on r.ean_number = e.physical_edition_ean
group by r.id

这按预期工作。我得到了返回的结果,但是我需要从另一个具有一对一关系的表(gardner_record

)中再添加几列到gardner_inventory_item

这是我尝试过的:

select book.*, array_agg(e) e_books from (
    select  r.*,
           i.price,
           i.discount,
           i.free_stock,
           i.report,
           i.report_date
    from gardner_record r
             inner join gardner_inventory_item i on r.ean_number = i.ean
    ) book
left join gardner_e_book_record e on book.ean_number = e.physical_edition_ean
group by book.id

但是它不起作用。该查询给出错误,指出modified_dategardner_record上的一列)必须按分组或聚合。

这是为什么?我在子查询中创建一个表。然后,我以ebooks的形式加入嵌套记录,并在array_agg()中使用select。这不是所有内容都汇总了吗?它可以在第一个查询中使用。

在概念上我在这里想念什么?

2 个答案:

答案 0 :(得分:1)

第一个查询不会产生相同的错误,因为(我想因为您没有公开)idPRIMARY KEY的{​​{1}},并且PK覆盖了同一列的所有列自Postgres 9.1起gardner_record子句中的表格。相关:

在第二个查询中,您已经汇总了 派生表 GROUP BY 。在外部的book中,SELECT不再具有该属性(派生的表簿没有PK),它仅覆盖了id列表中-并且还有{ {1}列表中未涵盖的{1}}。

这将起作用:

GROUP BY

或者,假设,我们也可以在gardner_inventory_item上进行汇总(因为您提到了1:1关系):

GROUP BY

更简单,更快。

答案 1 :(得分:1)

通常,未出现在聚合函数中的任何列都必须包含在GROUP BY子句中,但是,如果所选表具有主键,则只需将主键包括在GROUP BY中子句允许在不进行聚合的情况下选择该表的所有列,您可以在第一个查询中使用它。但是,这种方法does not work when the primary key is wrapped in a subquery由于Postgres优化器无法确定该列原来是主键了。

要解决此问题,您可以显式列出book子查询的所有列(这可能很麻烦)。

或者,您可以在子查询中联接gardner_recordgardner_e_book_record表并将其分组,然后再联接gardner_inventory_item。基本上,只需将第一个查询作为子查询,然后加入gardner_inventory_item表即可。示例:

select book_e_ebooks, i.* from (
        select r.*, array_agg(e) e_books from gardner_record r
        left join gardner_e_book_record e on r.ean_number = e.physical_edition_ean
        group by r.id
    ) book_e_ebooks
left join gardner_inventory_item i on book_e_ebooks.ean_number = i.ean;

但是您真的根本不需要子查询:

select r.*, i.*, array_agg(e) e_books from gardner_record r
left join gardner_inventory_item i on r.ean_number = i.ean
left join gardner_e_book_record e on r.ean_number = e.physical_edition_ean
group by r.id, i.id