Impostare i nomi sugli attributi durante la creazione di JSON con row_to_json


24

È possibile rinominare i f1, f2, f3...nomi predefiniti quando si utilizza la row_to_jsonfunzione solo per alcune colonne?

posso fare

row_to_json(customers)

ritorno

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

Ma se voglio solo nomi senza id_customer, devo usare

row_to_json(row(first_name, last_name))

e poi ottengo

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

E vorrei ottenere questo risultato con i nomi delle colonne predefiniti o con i miei. So di poter creare il mio tipo e utilizzo compositi

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

ma non è possibile farlo correttamente nella query senza creare quel tipo?


1
Inoltre, vedi: riferimento 1 e riferimento 2 per simili
MikeM,

Risposte:


17

Un'espressione di tabella comune consente di specificare esplicitamente gli alias, non solo per il CTE ma per le sue colonne.

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

Questo è diverso dall'esempio di @ dezso in quanto non utilizza col AS aliasper ogni colonna in un SELECTelenco; alias i nomi delle colonne nell'alias della tabella CTE.

Ho usato VALUESun'espressione come sottoquery ma puoi usare SELECTqualunque cosa tu voglia; il punto è che qualsiasi alias di colonna fornito o assunto nella sottoquery può essere ignorato nella definizione CTE specificando un elenco di nomi di colonne.

Puoi fare la stessa cosa in una sottoquery, di nuovo invece di usare AS alias:

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

Questo non funziona ROWdirettamente con un'espressione; puoi lanciare solo ROWa un tipo concreto, non puoi alias.

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);

C'è qualche differenza (a parte lo stile e / o la leggibilità) tra le nostre soluzioni (utilizzo, prestazioni, ecc.)?
dezso

@dezso No, e probabilmente avrei dovuto solo postare un commento. Scusate.
Craig Ringer

Penso che sia OK Ho persino votato a fondo la tua risposta in quanto contiene informazioni utili che la mia non contiene.
dezso

Esiste una sintassi per ottenere gli alias di colonna in modo dinamico? Sto estraendo da uno schema EAV (valore attributo entità) in cui vengono selezionati anche i nomi delle chiavi desiderati dalla colonna attributo.nome.
Chris

@Chris Avrai bisogno delle funzioni json più sofisticate in 9.4.
Craig Ringer

23
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

farà ciò che vuoi senza alcun impatto sulle prestazioni (e non è troppo dettagliato):

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

4
Questa risposta è una gemma.
Tiffon

Grazie mille mi hai salvato il pomeriggio, peccato che questo non sia un esempio citato nell'API PostgreSQL. Sapevo che era possibile
calunnia il

9

Puoi fare qualcosa del genere:

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

(Naturalmente, lo stesso può essere ottenuto con

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

ma ho trovato il primo più leggibile.)

Nella WITHparte puoi costruire file di qualsiasi struttura al volo.


Per concatenare i non-jsonb con jsonb :: SELECT row_to_json (r. *) FROM (SELEZIONA c1, c2 :: jsonb FROM us_ca_monterey_aoc.test) come r
Andrew Scott Evans

9

È possibile utilizzare 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;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.