Row_to_json ile JSON oluştururken adları özelliklere ayarlayın


24

Yalnızca bazı sütunlarda işlev f1, f2, f3...kullanılırken varsayılan adları yeniden adlandırmak mümkün müdür row_to_json?

Yapabilirim

row_to_json(customers)

dönen

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

Ama sadece isimsiz isimler kullanmak id_customeristersem kullanmak zorundayım.

row_to_json(row(first_name, last_name))

ve sonra anladım

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

Ve bu sonucu ya varsayılan sütun isimleriyle ya da kendiminkilerle almak istiyorum. Kendi bileşik tipimi oluşturabileceğimi ve kullanabileceğimi biliyorum

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

Ancak bu tür oluşturmadan sorguda doğru yapmak mümkün değil mi?


1
Ayrıca bakınız: referans 1 ve benzer referans 2
MikeM

Yanıtlar:


17

Yaygın bir tablo ifadesi, yalnızca CTE için değil sütunlar için takma adları açıkça belirtmenize izin verir.

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

Bu, @ dezso'nun bir örneğindeki listedeki col AS aliasher sütun için kullanmadığı örneğinden farklıdır SELECT; CTE tablo takma adındaki sütun adlarını taklit eder.

Bir VALUESifadeyi alt sorgu olarak kullandım, ancak SELECTne istersen onu kullanabilirsin ; Buradaki nokta, alt sorguda hangi sütun takma adlarının sağlandığı veya varsayıldığı varsayılırsa, bir sütun adı listesi belirtilerek CTE tanımında geçersiz kılınabilir.

Aynı şeyi tekrar kullanmak yerine, bir alt sorguda da yapabilirsiniz AS alias:

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

Bu bir ile çalışmıyor ROW doğrudan ifade ; Sadece ROWsomut bir türe dökebilirsin, takma ismini alamazsın.

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

Çözümlerimiz arasında (kullanım, performans vb.) Herhangi bir fark var mı (stil ve / veya okunabilirlik dışında)?
dezso

@dezso Hayır ve muhtemelen bir yorum yazmalıydım. Üzgünüm.
Craig Ringer

Bence bu iyi. Cevabınızı b / c bile atamadım benim ki olmayan yararlı bilgiler içeriyor.
dezso

Sütun takma adlarını dinamik olarak almak için bir sözdizimi var mı? İstenen anahtar adlarının attribute.name sütunundan da seçildiği bir EAV (varlık özellik değeri) şemasından çekiyorum.
Chris

@Chris 9.4'te daha sofistike json fonksiyonlarına ihtiyacınız olacak.
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

herhangi bir performans etkisi olmadan istediğinizi yapacak (ve çok ayrıntılı değil):

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

4
Bu cevap bir mücevher.
16'da

Öğleden sonramı kurtardığın için çok teşekkürler, bu çok kötü bir şey PostgreSQL API’sinde bu alıntı sayılmaz bir örnek değil. Bunun mümkün olduğunu biliyordum
jlandercy

9

Böyle bir şey yapabilirsiniz:

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

(Tabii ki, aynı ile elde edilebilir

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

ama eskisini daha okunaklı buldum.)

Kısmen WITHanında herhangi bir yapının satırlarını inşa edebilirsiniz.


Jsonb olmayan jsonb :: SELECT ile satır_to_json (r. *) FROM (SELECT c1, c2 :: jsonb FR_ us_ca_monterey_aoc.test) ile r
Andrew Scott Evans

9

Kullanabilirsiniz 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;
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.