web-dev-qa-db-fra.com

Définissez des noms pour les attributs lors de la création de JSON avec row_to_json

Est-il possible de renommer les noms par défaut f1, f2, f3... En utilisant la fonction row_to_json Pour seulement certaines colonnes?

Je peux faire

row_to_json(customers)

de retour

{"id_customer":2,"first_name":"bla","last_name":"second_bla"}

Mais si je veux seulement des noms sans id_customer, Je dois utiliser

row_to_json(row(first_name, last_name))

et puis je reçois

{"f1":"bla","f2":"second_bla"}

Et je voudrais obtenir ce résultat avec les noms de colonnes par défaut ou les miens. Je sais que je peux créer mon propre type composite et l'utiliser

row_to_json(row(first_name, last_name))::my_custom_type

mais n'est-il pas possible de le faire directement dans la requête sans créer ce type?

25
boobiq
select 
   c.id,
   (select row_to_json(_) from (select c.first_name, c.last_name) as _) as first_last,
   c.age
from
   customers as c

fera ce que vous voulez sans aucun impact sur les performances (et n'est pas trop verbeux):

  id  |   first_last                                |   age
------+---------------------------------------------+---------
  1   | {"fisrt_name": "John", "last_name": "Smit"} |   34
25
Anatoly Ressin

Une expression de table commune vous permet de spécifier explicitement des alias, non seulement pour le CTE mais pour ses colonnes.

WITH data(col1,col2,cola,colb) AS (
  VALUES (1,2,'fred','bob')
)
SELECT row_to_json(data) FROM data;

Ceci est différent de l'exemple de @ dezso en ce qu'il n'utilise pas col AS alias pour chaque colonne d'une liste SELECT; il alias les noms de colonne dans l'alias de table CTE.

J'ai utilisé une expression VALUES comme sous-requête mais vous pouvez utiliser une SELECT comme bon vous semble; le fait est que les alias de colonne fournis ou supposés dans la sous-requête peuvent être remplacés dans la définition CTE en spécifiant une liste de noms de colonnes.

Vous pouvez faire la même chose dans une sous-requête, à nouveau au lieu d'utiliser AS alias:

SELECT row_to_json(data) 
FROM (VALUES (1,2,'fred','bob')) data(col1,col2,cola,colb);

Cela ne fonctionne pas directement avec une expression ROW; vous pouvez uniquement convertir un ROW en un type concret, vous ne pouvez pas l'aliaser.

regress=> SELECT ROW(1,2,'fred','bob') AS x(a,b,c,d);
ERROR:  syntax error at or near "("
LINE 1: SELECT ROW(1,2,'fred','bob') AS x(a,b,c,d);
17
Craig Ringer

Vous pouvez faire quelque chose comme ça:

WITH r AS (
  SELECT 'bla' AS name1, 'otherbla' AS name2
)
SELECT row_to_json(r.*)
FROM r
;

(Bien sûr, la même chose peut être obtenue avec

SELECT row_to_json(r.*)
FROM (SELECT 'bla' AS name1, 'otherbla' AS name2) r
;

mais j'ai trouvé l'ancien plus lisible.)

Dans la partie WITH, vous pouvez construire des lignes de n'importe quelle structure à la volée.

9
dezso

Vous pouvez utiliser json_build_object.

SELECT 
  json_build_object('id', data.customer_id, 'first_name', data.first_name, 'last_name', data.last_name) as your_json
FROM data;
9
aheuermann