我试图将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_date
(gardner_record
上的一列)必须按分组或聚合。
这是为什么?我在子查询中创建一个表。然后,我以ebooks
的形式加入嵌套记录,并在array_agg()
中使用select
。这不是所有内容都汇总了吗?它可以在第一个查询中使用。
在概念上我在这里想念什么?
答案 0 :(得分:1)
第一个查询不会产生相同的错误,因为(我想因为您没有公开)id
是PRIMARY 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_record
和gardner_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