首页 > 解决方案 > `SELECT a.*, array_agg(b)` 需要 `a` 中所有列的 `GROUP BY`

问题描述

问题: 如何指定我想要一个与by (以及所有其他列)child相关的数组,而无需实际指定 中的每一列?parentuniq_hashGROUP BY

数据库是PostgreSQL


我有这些表:parentschildren

parents

| id | col1 | col2 | ... | col250 | uniq_hash |
|----|------|------|-----|--------|-----------|
| 1  |      |      |     |        | <hash>    |

children

| id | bcol1 | bcol2 | ... | bcol50 | uniq_hash |
|----|-------|-------|-----|--------|-----------|
| 1  |       |       |     |        | <hash>    |
       +---------+
   +---+  Parent +---+
   |   +----+----+   |
   |        |        |
+--v--+  +--v--+  +--v--+
|Child|  |Child|  |Child|
+-----+  +-----+  +-----+


我正在尝试将数组添加childSELECT * parent FROM parents WHERE ...;查询中。

生成的查询将类似于:

SELECT parents.*, array_agg(children) as children FROM parents LEFT JOIN children ON parents.uniq_hash = children.uniq_hash WHERE ...;


问题是parents大约 250 列宽,要做到这一点,我似乎需要将每一列parents列为GROUP BY. 这是……次优的。


已经尝试过了,它执行了——但它只返回两列(即:它缺少parent数据列上的标题):

SELECT parents, array_agg(children) as children FROM parents LEFT JOIN children ON parents.uniq_hash = children.uniq_hash WHERE ... GROUP BY parents;

标签: sqlpostgresql

解决方案


事实上,你没有。你可以使用:

GROUP BY parents.id

如果id声明为uniqueor primary key,那么 Postgres 将接受该语法。

如果id没有以这种方式声明,您可以使用相关子查询:

SELECT p.*,
       (SELECT array_agg(c.children)
        FROM children c
        WHERE p.uniq_hash = c.uniq_hash
       ) as children
FROM parents p;

推荐阅读