Sql 为什么这个查询需要聚合?

Sql 为什么这个查询需要聚合?,sql,postgresql,subquery,aggregate,Sql,Postgresql,Subquery,Aggregate,我正在尝试将两个表连接到一个表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 这正如预期的那样有效。我得到了结果,但我还需要从另一个名为gardne

我正在尝试将两个表连接到一个表
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\u inventory\u 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_date
(gardner_record上的一列)需要按分组或聚合

为什么会这样?我在子查询中创建一个表。然后我将嵌套记录作为
ebooks
加入,并在
select
中使用
array\u agg()
。这难道不意味着这一切都是聚合的吗?它在第一个查询中工作


从概念上讲,我遗漏了什么?

第一个查询不会产生相同的错误,因为(我假设您没有披露)
id
gardner\u record
主键,并且自Postgres 9.1以来,PK覆盖了
GROUP BY
子句中相同表的所有列。相关的:

在第二个查询中,在聚合之前,您已经形成了派生表
book
。在外部
SELECT
中,
id
不再具有该属性(派生的表簿没有主键),它只在
groupby
列表中覆盖自己-还有
gardner\u inventory\u item
中的其他列,它们在
groupby
列表中根本没有覆盖

这将有助于:

SELECT r.*
     , i.price
     , i.discount
     , i.free_stock
     , i.report
     , i.report_date
     , array_agg(e) AS e_books
FROM   gardner_record r
JOIN   gardner_inventory_item i ON r.ean_number = i.ean
LEFT   JOIN  gardner_e_book_record e
GROUP  BY r.id, i.ean;  -- Assuming these are PKs of each table
或者,假设我们也可以在
物理版
上进行聚合(因为您提到了1:1的关系):


更简单、更快。

第一个查询不会产生相同的错误,因为(我假设您没有披露)
id
gardner\u record
主键,并且自Postgres 9.1以来,PK覆盖了
GROUP BY
子句中相同表的所有列。相关的:

在第二个查询中,在聚合之前,您已经形成了派生表
book
。在外部
SELECT
中,
id
不再具有该属性(派生的表簿没有主键),它只在
groupby
列表中覆盖自己-还有
gardner\u inventory\u item
中的其他列,它们在
groupby
列表中根本没有覆盖

这将有助于:

SELECT r.*
     , i.price
     , i.discount
     , i.free_stock
     , i.report
     , i.report_date
     , array_agg(e) AS e_books
FROM   gardner_record r
JOIN   gardner_inventory_item i ON r.ean_number = i.ean
LEFT   JOIN  gardner_e_book_record e
GROUP  BY r.id, i.ean;  -- Assuming these are PKs of each table
或者,假设我们也可以在
物理版
上进行聚合(因为您提到了1:1的关系):


更简单、更快。

通常,聚合函数中未出现的任何列都必须包含在
GROUP BY
子句中,但是,如果所选表具有主键,则只需将主键包含在
GROUP BY
子句中,即可选择该表的所有列而无需进行聚合,您在第一个查询中使用的。但是,由于Postgres优化器无法判断该列原来是主键,因此使用这种方法

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

或者,您可以在子查询中连接并分组
gardner_记录
gardner_电子书_记录
表,然后连接
gardner_库存项目
。基本上,只需将第一个查询作为子查询,然后加入
gardner\u inventory\u item
表。例如:

从中选择图书电子书,i.*(
从gardner_记录r中选择r.*,数组_agg(e)电子书
左连接gardner_e_book_record e on r.ean_number=e.physical_edition_ean
按r.id分组
)电子书
left join gardner_inventory_book_e_电子书上的项目i.ean_number=i.ean;
但您实际上根本不需要子查询:

从gardner\u记录r中选择r.*、i.*、数组\u agg(e)电子书
左连接gardner\u库存\u r.ean上的项目i\u编号=i.ean
左连接gardner_e_book_record e on r.ean_number=e.physical_edition_ean
按r.id、i.id分组

通常,聚合函数中未出现的任何列都必须包含在
GROUP BY
子句中,但是,如果所选表具有主键,则只需将主键包含在
GROUP BY
子句中,即可选择该表的所有列而无需进行聚合,您在第一个查询中使用的。但是,由于Postgres优化器无法判断该列原来是主键,因此使用这种方法

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

或者,您可以在子查询中连接并分组
gardner_记录
gardner_电子书_记录
表,然后连接
gardner_库存项目
。基本上,只需将第一个查询作为子查询,然后加入
gardner\u inventory\u item
表。例如:

从中选择图书电子书,i.*(
从gardner_记录r中选择r.*,数组_agg(e)电子书
左连接gardner_e_book_record e on r.ean_number=e.physical_edition_ean
按r.id分组
)电子书
left join gardner_inventory_book_e_电子书上的项目i.ean_number=i.ean;
但您实际上根本不需要子查询:

从gardner\u记录r中选择r.*、i.*、数组\u agg(e)电子书
左连接gardner\u库存\u r.ean上的项目i\u编号=i.ean
左连接gardner_e_book_record e on r.ean_number=e.physical_edition_ean
按r.id、i.id分组

请为您的问题添加示例数据。