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.