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分组
请为您的问题添加示例数据。