How can I make a sql that contains an array of objects and that those objects contain 2 column data?

1

I have this sql

The result of the 2 columns modelos_id and modelos_nombre I would like to join within objects, I try to do as it says the documentation .

Here's what I'm trying to do , the query is as follows:

SELECT mar.nombre AS marcas, json_object(array_agg(mod.id), array_agg(mod.nombre)) as modelos
FROM marcas AS mar
INNER JOIN modelos AS mod ON (mar.id=mod.marcas_id)
GROUP BY mar.nombre
ORDER BY mar.nombre

But this one returns to me:

  

ERROR: the json_object (integer [], character varying []) function does not exist

    
asked by Pablo Contreras 30.04.2017 в 03:55
source

2 answers

2

Returning an object jsonb

If you want to respect the GROUP BY with mar.name and in a single field have an object with the id as a key and the name as a value you can use the function jsonb_object_agg :

SELECT mar.nombre AS marcas, 
    jsonb_object_agg(mod.id,mod.nombre) as modelos_nombre
FROM marcas AS mar
INNER JOIN modelos AS mod ON (mar.id=mod.marcas_id)
GROUP BY mar.nombre
ORDER BY mar.nombre

This results in

LG       {"1":"LG-001","2":"LG-002","3":"LG-003"}
Samsung  {"4":"Sam-004","5":"Sam-005","6":"Sam-006"}
Sonyview {"7":"Sony-007","8":"Sony-008","9":"Sony-009"}

Returning an array json

If you want to respect the GROUP BY with mar.name and in a single field have the list (or array ) of id and brand name will be you can use the function json_agg for the aggregate function and json_build_object to create the individual element:

SELECT mar.nombre AS marcas, 
    json_agg(json_build_object('id',mod.id,'mod',mod.nombre)) as modelos_nombre
FROM marcas AS mar
INNER JOIN modelos AS mod ON (mar.id=mod.marcas_id)
GROUP BY mar.nombre
ORDER BY mar.nombre

Different possibilities in json_build_object are giving you different results. You can try the one you want. With this the result is:

LG       [{"id":1,"mod":"LG-001"},{"id":2,"mod":"LG-002"},{"id":3,"mod":"LG-003"}]
Samsung  [{"id":4,"mod":"Sam-004"},{"id":5,"mod":"Sam-005"},{"id":6,"mod":"Sam-006"}]
Sonyview [{"id":7,"mod":"Sony-007"},{"id":8,"mod":"Sony-008"},{"id":9,"mod":"Sony-009"}]

You can try json_build_object(mod.id::text,mod.nombre) so that the id is the key of the pair and marks the value.

json vs jsonb

For the purposes of this problem it does not matter, you can use array or object in both variants. I recommend jsonb, but that's another topic.

Returning a% pure% of records

The following returns a array array , again here you can put inside the array_agg what you want so that the internal element is of the type you need.

SELECT mar.nombre AS marcas, 
    array_agg(array[mod.id::text,mod.nombre]) as modelos_nombre
FROM marcas AS mar
INNER JOIN modelos AS mod ON (mar.id=mod.marcas_id)
GROUP BY mar.nombre
ORDER BY mar.nombre

What can be put inside array_agg?

Alternatives to put inside array_agg. The problem of putting an array inside is that you have to pass everything to the same type, if you want to respect the types a good alternative is to use row:

  • ARRAY that returns a record (tuple) respecting the types

Anything that returns a single value can be put inside row(mod.id,mod.nombre) , for example any function that returns a json (which would not make much sense, because it would be mixing json within common arrays).

    
answered by 30.04.2017 / 15:35
source
1

Maybe this?

SELECT mar.nombre AS marcas, 
       row_to_json(row(mod.id, mod.nombre)) as modelos
FROM marcas AS mar
INNER JOIN modelos AS mod ON (mar.id=mod.marcas_id)
GROUP BY mod.id,mar.nombre
ORDER BY mar.nombre
    
answered by 30.04.2017 в 15:04