it-swarm-eu.dev

Při vytváření JSON pomocí row_to_json nastavte názvy na atributy

Je možné při použití funkce f1, f2, f3... Přejmenovat výchozí názvy row_to_json Pouze u některých sloupců?

Můžu udělat

row_to_json(customers)

vracející se

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

Ale pokud chci pouze jména bez id_customer, Musím použít

row_to_json(row(first_name, last_name))

a pak dostanu

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

A já bych chtěl získat tento výsledek buď s výchozím názvem sloupce, nebo vlastním. Vím, že mohu vytvořit svůj vlastní kompozitní typ a použití

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

ale není možné to udělat přímo v dotazu bez vytvoření tohoto typu?

25
boobiq
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

udělá, co chcete, bez jakéhokoli dopadu na výkon (a není příliš podrobný):

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

Společný výraz tabulky umožňuje explicitně zadat aliasy, nejen pro CTE, ale pro jeho sloupce.

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

To se liší od příkladu @ dezso v tom, že nepoužívá col AS alias pro každou sloupec v seznamu SELECT; aliasy názvů sloupců v aliasu tabulky CTE.

Jako poddotaz jsem použil výraz VALUES, ale můžete použít SELECT, co se vám líbí; jde o to, že cokoli aliasů sloupců, které jsou poskytnuty nebo převzaty v poddotazu, může být potlačeno v definici CTE zadáním seznamu sloupců-jmen.

Totéž můžete udělat v poddotazu, namísto použití AS alias:

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

Toto nefunguje přímo s výrazem ROW; můžete pouze přetypovat ROW na konkrétní typ, nemůžete jej také aliasovat.

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);
17
Craig Ringer

Můžete udělat něco takového:

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

(Samozřejmě toho samého lze dosáhnout pomocí

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

ale zjistil jsem, že první je čitelnější.)

V části WITH můžete sestavit řádky libovolné struktury za běhu.

9
dezso

Můžeš použít 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;
9
aheuermann