Tetapkan nama menjadi atribut saat membuat JSON dengan row_to_json


24

Apakah mungkin untuk mengganti f1, f2, f3...nama nama standar saat menggunakan row_to_jsonfungsi hanya untuk beberapa kolom?

dapat saya lakukan

row_to_json(customers)

kembali

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

Tetapi jika saya hanya ingin nama tanpa id_customer, saya harus menggunakan

row_to_json(row(first_name, last_name))

dan kemudian saya dapatkan

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

Dan saya ingin mendapatkan hasil ini dengan nama kolom default atau nama saya sendiri. Saya tahu saya bisa membuat tipe dan penggunaan komposit sendiri

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

tetapi apakah tidak mungkin untuk melakukannya dengan benar dalam permintaan tanpa membuat jenis itu?


1
Juga, lihat: referensi 1 dan referensi 2 untuk serupa
— MikeM

Jawaban:


17

Ekspresi tabel yang umum memungkinkan Anda untuk menentukan alias secara eksplisit, tidak hanya untuk CTE tetapi untuk kolomnya.

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

Ini berbeda dengan contoh @ dezso karena tidak digunakan col AS aliasuntuk setiap col dalam SELECTdaftar; alias nama kolom dalam alias tabel CTE.

Saya telah menggunakan VALUESekspresi sebagai subquery tetapi Anda dapat menggunakan SELECTapa pun yang Anda suka; intinya adalah bahwa apa pun alias kolom yang disediakan atau diasumsikan dalam subquery dapat ditimpa dalam definisi CTE dengan menetapkan daftar nama-kolom.

Anda bisa melakukan hal yang sama di subquery, lagi daripada menggunakan AS alias:

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

Ini tidak bekerja dengan ROWekspresi secara langsung; Anda hanya bisa melemparkan ROWke tipe beton, Anda tidak bisa menamainya.

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

Apakah ada perbedaan (terlepas dari gaya dan / atau keterbacaan) antara solusi kami (penggunaan, kinerja, dll.)?
— dezso

@dezso Tidak, dan saya mungkin seharusnya mengirim komentar. Maaf.
— Craig Ringer

Saya pikir ini baik-baik saja. Saya bahkan membatalkan jawaban Anda karena itu berisi informasi berguna yang tidak saya miliki.
— dezso

Apakah ada sintaks untuk mendapatkan alias alias kolom secara dinamis? Saya menarik dari skema EAV (nilai atribut entitas) di mana nama kunci yang diinginkan juga dipilih dari kolom attribute.name.
— Chris

@ Chris Anda membutuhkan fungsi json yang lebih canggih di 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

akan melakukan apa yang Anda inginkan tanpa dampak kinerja apa pun (dan tidak terlalu bertele-tele):

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

4
Jawaban ini adalah permata.
— tiffon

Terima kasih banyak, Anda telah menyelamatkan sore saya, sayang sekali ini bukan contoh yang dikutip di PostgreSQL API. Saya tahu itu mungkin
— jlandercy

9

Anda dapat melakukan sesuatu seperti ini:

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

(Tentu saja, hal yang sama dapat dicapai dengan

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

tapi saya menemukan yang pertama lebih mudah dibaca.)

Pada WITHbagian ini Anda dapat membuat baris struktur apa saja dengan cepat.


Untuk menggabungkan non-jsonb dengan jsonb :: SELECT row_to_json (r. *) FROM (SELECT c1, c2 :: jsonb FROM us_ca_monterey_aoc.test) sebagai r
— Andrew Scott Evans

9

Anda bisa menggunakannya 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;
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.