Setzen Sie Namen auf Attribute, wenn Sie JSON mit row_to_json erstellen


24

Ist es möglich, Standardnamen umzubenennen, f1, f2, f3...wenn die row_to_jsonFunktion nur für einige Spalten verwendet wird?

ich kann

row_to_json(customers)

zurückkehren

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

Aber wenn ich nur Namen ohne will id_customer, muss ich verwenden

row_to_json(row(first_name, last_name))

und dann verstehe ich

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

Und ich möchte dieses Ergebnis entweder mit Standardspaltennamen oder mit meinen eigenen erhalten. Ich weiß, dass ich meinen eigenen zusammengesetzten Typ erstellen und verwenden kann

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

Aber ist es nicht möglich, es in der Abfrage richtig zu machen, ohne diesen Typ zu erstellen?


1
Siehe auch: Referenz 1 und Referenz 2 für ähnliche
— MikeM

Antworten:


17

Mit einem allgemeinen Tabellenausdruck können Sie Aliase nicht nur für den CTE, sondern auch für seine Spalten explizit angeben.

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

Dies unterscheidet sich vom Beispiel von @ dezso darin, dass es nicht col AS aliasfür jede Spalte in einer SELECTListe verwendet wird. Es werden die Spaltennamen im CTE-Tabellenalias aliasisiert.

Ich habe einen VALUESAusdruck als Unterabfrage verwendet, aber Sie können einen SELECTbeliebigen Ausdruck verwenden . Der Punkt ist, dass alle Spaltenaliasnamen, die in der Unterabfrage bereitgestellt oder angenommen werden, in der CTE-Definition durch Angabe einer Spaltennamensliste überschrieben werden können.

Sie können dasselbe auch in einer Unterabfrage tun, anstatt Folgendes zu verwenden AS alias:

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

Dies funktioniert nicht ROWdirekt mit einem Ausdruck. Sie können einen nur ROWin einen konkreten Typ umwandeln, Sie können ihn nicht aliasisieren.

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

Gibt es einen Unterschied (abgesehen von Stil und / oder Lesbarkeit) zwischen unseren Lösungen (Verwendung, Leistung usw.)?
— Dezso

@dezso Nein, und ich hätte wahrscheinlich gerade einen Kommentar schreiben sollen. Es tut uns leid.
— Craig Ringer

Ich denke das ist OK. Ich habe Ihre Antwort sogar positiv bewertet, da sie nützliche Informationen enthält, die meine nicht enthält.
— Dezso

Gibt es eine Syntax zum dynamischen Abrufen der Spaltenaliase? Ich beziehe mich auf ein EAV-Schema (Entity Attribute Value), bei dem die gewünschten Schlüsselnamen auch aus der Spalte attribute.name ausgewählt werden.
— Chris

@Chris In 9.4 benötigen Sie die anspruchsvolleren json-Funktionen.
— 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

wird tun, was Sie wollen, ohne Leistungseinbußen (und ist nicht zu ausführlich):

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

4
Diese Antwort ist ein Juwel.
— Tiffon

Vielen Dank, dass Sie meinen Nachmittag gerettet haben, schade, dass dies kein zitiertes Beispiel in der PostgreSQL-API ist. Ich wusste, dass es möglich war
— Verleumdung

9

Sie können so etwas tun:

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

(Dasselbe kann natürlich auch mit erreicht werden

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

aber ich fand das erstere lesbarer.)

In dem WITHTeil können Sie Reihen beliebiger Strukturen im laufenden Betrieb erstellen.


Verketten von non-jsonb mit jsonb :: SELECT row_to_json (r. *) FROM (SELECT c1, c2 :: jsonb FROM us_ca_monterey_aoc.test) als r
— Andrew Scott Evans

9

Sie können verwenden 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;
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.