聚合查询中的单个列并包含许多列

Fab*_*tté 3 sql postgresql aggregate-functions

当查询中有许多其他列时,是否有适当的方法聚合单个列?

我已经试过了这个有效的答案,但是我的查询变得更加冗长。

我当前的查询如下所示:

SELECT t1.foo1, t1.foo2, t2.foo3, t2.foo4, string_agg(t3.aggregated_field, ', ')
FROM tbl1 t1
LEFT JOIN tbl2 t2 ON t1.id = t2.fkeyid
LEFT JOIN tbl3 t3 ON t2.id = t3.fkeyid
GROUP BY t1.foo1, t1.foo2, t2.foo3, t2.foo4, t2.foo5, t2.foo6
ORDER BY t2.foo5, t2.foo6
Run Code Online (Sandbox Code Playgroud)

该查询具有更多字段和LEFT JOINs,重要的部分是所有这些字段都具有1到1或1到0的关系,除了上面要t3.aggregated_field在上面的伪查询中表示的要聚合的1到n的一个字段。

当我使用汇总函数时,SELECT和中列出的所有字段都ORDER BY必须汇总或成为GROUP BY子句的一部分。这使我的查询方式比现在更加冗长。

也就是说,假设foo1是主键,则在重复此字段时,除其他字段外的所有其他字段aggregated_field也相等。我希望将这些重复的行作为具有聚合字段值的单行结果。(基本上是a select distinct,带有汇总列)

是否有更好的方法来执行此操作(而不必将所有其他字段都放入GROUP BY),还是应该仅对后端执行的结果集进行迭代,以对获取此1到n关系的每一行执行查询?


服务器正在运行PostgreSQL 9.1.9,更具体地说:

x86_64-unknown-linux-gnu上的PostgreSQL 9.1.9,由gcc(GCC)4.1.2 20080704(Red Hat 4.1.2-54)编译,64位

Erw*_*ter 5

简单查询

使用PostgreSQL 9.1或更高版本可以更加简单。如这个紧密相关的答案中所述:

对于表GROUP BY主键就足够了。以来:

foo1是主键

..您可以将示例简化为:

SELECT foo1, foo2, foo3, foo4, foo5, foo6, string_agg(aggregated_field, ', ')
FROM   tbl1
GROUP  BY 1
ORDER  BY foo7, foo8;  -- have to be spelled out, since not in select list!
Run Code Online (Sandbox Code Playgroud)

查询多个表

但是,由于您具有:

还有更多的字段和LEFT JOIN,重要的部分是所有这些字段都具有1到1或1到0的关系,除了我要聚合的一个字段是1到n

..它应该更快,更简单地进行汇总,然后再加入

SELECT t1.foo1, t1.foo2, ...
     , t2.bar1, t2.bar2, ...
     , a.aggregated_col 
FROM   tbl1 t1
LEFT   JOIN tbl2 t2 ON ...
...
LEFT   JOIN (
   SELECT some_id, string_agg(agg_col, ', ') AS aggregated_col
   FROM   agg_tbl a ON ...
   GROUP  BY some_id
   ) a ON a.some_id = ?.some_id
ORDER  BY ...
Run Code Online (Sandbox Code Playgroud)

这样,查询的大部分就根本不需要聚合。

我最近在SQL Fiddle中提供了一个测试用例,以证明此相关答案中的要点:

因为您是指此相关答案:不,DISTINCT在这种情况下完全没有帮助。