postgresql – 从别名创建较小的行并保留列名

使用Postgres:

SELECT users."name" AS "name"
    , array_to_json(array_agg(sites)) as sites
FROM remodel.users AS users
JOIN remodel.user_sites AS user_sites
    ON users.id=user_sites.user
JOIN remodel.sites AS sites
    ON sites.id=user_sites.site
GROUP BY "users".id
;

目前生产

"Toby";"[{"id":1,"name":"Village","created":"2015-08-10T15:22:36.622298"},
         {"id":2,"name":"Manor","created":"2015-08-10T15:22:43.614551"}]"
"Amy";"[{"id":3,"name":"Park","created":"2015-08-10T15:22:48.810872"}]"
"Anne";"[{"id":2,"name":"Manor","created":"2015-08-10T15:22:43.614551"},
         {"id":1,"name":"Village","created":"2015-08-10T15:22:36.622298"},
         {"id":3,"name":"Park","created":"2015-08-10T15:22:48.810872"}]"

但是我不想在JSON输出中有“id”字段.

将网站选择更改为

array_to_json(array_agg(row(sites."name", sites.created))) as sites

导致字段丢失名称

"[{"f1":"Village","f2":"2015-08-10T15:22:36.622298"},
  {"f1":"Manor","f2":"2015-08-10T15:22:43.614551"}]"

和尝试(什么将是一个可怕的)子选择

, array_to_json(array_agg((SELECT "name", created FROM sites))) as sites

可以理解地抛出一个

ERROR: relation “sites” does not exist

并使用from子句中的select删除id可防止连接表.

我希望尽可能保留列信息,不仅仅是为了转换为JSON,而是包含在更大更复杂的查询中,因此首选执行数组选择而不使用JSON.

最佳答案
一个想法是创建一个包含您感兴趣的列的内联视图:

SELECT users."name" AS "name"
     , array_to_json(array_agg(sites)) as sites
FROM remodel.users AS users
JOIN remodel.user_sites AS user_sites
    ON users.id=user_sites.user
CROSS JOIN LATERAL (
    SELECT name, created 
    FROM remodel.sites AS s
    WHERE s.id=user_sites.site
) AS sites
GROUP BY "users".id

通过使用LATERAL,您可以在内联视图中引用“兄弟”.由于JOIN条件是视图的一部分,因此可以使用CROSS JOIN.

转载注明原文:postgresql – 从别名创建较小的行并保留列名 - 代码日志