Estou tentando combinar vários objetos JSON em um grande objeto no Postgres.
Eu poderia fazer isso com um extra SELECT row_to_json
(como no meu primeiro exemplo), mas dessa forma ele cria um objeto extra, o que eu não quero porque esse objeto já está criado pelo array_agg
qual está enrolado nele. No entanto, array_agg
não aceita várias colunas. Então tentei resolver com o operador de concatenação, mas não consigo usar AS
com ele, que é necessário para dar as chaves corretas aos objetos. (E o tipo de dados se torna text
, cuja to_json
função escapa, o que não é perfeito, mas posso conviver com isso).
SELECT to_json(array_agg(g)) FROM (SELECT
(SELECT row_to_json(e) FROM
(SELECT ST_AsGeoJSON(ST_Union(cargogeom))::json AS geometry,
(SELECT row_to_json(d) FROM
(SELECT cargoid AS voyageid, voyages, cargovalues) d) AS properties,
to_json('Feature'::text) AS type) e) AS "ThisKeyShouldBeGone"
FROM (SELECT
cargoid,
cargogeom,
sum(cargonumvoyages) AS voyages,
sum(cargovalues) AS cargovalues
FROM "bgbCargoMinardSplit"
GROUP BY cargoid, cargogeom)
AS x
WHERE cargoid = 1000
GROUP BY cargoid, voyages, cargovalues
ORDER BY cargoid ) AS g;
cargoid,
cargogeom,
sum(cargonumvoyages) AS voyages,
sum(cargovalues) AS cargovalues
FROM "bgbCargoMinardSplit"
GROUP BY cargoid, cargogeom)
AS x
WHERE cargoid = 1000
GROUP BY cargoid, voyages, cargovalues
ORDER BY cargoid ) AS g;
O que resulta em
[
{
"ThisKeyShouldBeGone": {
"geometry": {
"type": "MultiLineString",
"coordinates": [
[
[..]
]
]
},
"properties": {
[..]
},
"type": "Feature"
}
},
{
"ThisKeyShouldBeGone": {
"geometry": [..]
Então, para me livrar da chave "ThisKeyShouldBeGone", tentei usar operadores concatenados, mas desta forma não posso usar AS
:
SELECT to_json(array_agg(g)) FROM (SELECT
(SELECT ST_AsGeoJSON(ST_Union(cargogeom))::json || ',' ||
(SELECT row_to_json(d) FROM
(SELECT cargoid AS voyageid, voyages, cargovalues) d) || ',' ||
to_json('Feature'::text) AS type)
FROM (SELECT
cargoid,
cargogeom,
sum(cargonumvoyages) AS voyages,
sum(cargovalues) AS cargovalues
FROM "bgbCargoMinardSplit"
GROUP BY cargoid, cargogeom)
AS x
WHERE cargoid = 1000
GROUP BY cargoid, voyages, cargovalues
ORDER BY cargoid ) AS g;
Então, existe uma maneira de combinar o operador concatenado com AS
, ou talvez haja uma maneira melhor de fazer isso, já que o operador concatenado também não é perfeito.
Não tenho certeza do que você está perguntando, mas no Postgres 9.3 ou posterior você pode usar
json_agg()
para traduzir uma tabela inteira em uma matriz JSON de registros. Prepare as linhas em uma única subconsulta e alimente linhas inteirasjson_agg()
usando o alias da tabela:Múltiplas camadas de subseleções aninhadas como você exibe parecem desnecessárias.
Exemplo simples:
Consulta:
Resultado:
SQL Fiddle.