Встановлюйте імена для атрибутів під час створення JSON за допомогою row_to_json


24

Чи можливо перейменовувати f1, f2, f3...імена за замовчуванням при використанні row_to_jsonфункції лише для деяких стовпців?

я можу зробити

row_to_json(customers)

повернення

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

Але якщо я хочу лише імена без id_customer, я повинен використовувати

row_to_json(row(first_name, last_name))

і тоді я отримую

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

І я хотів би отримати цей результат або з назвою стовпців за замовчуванням, або зі своїм власним. Я знаю, що можу створити власний композитний тип та використовувати

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

але чи не можливо це зробити правильно в запиті, не створюючи цього типу?


1
Також дивіться: посилання 1 та посилання 2 для подібних
MikeM

Відповіді:


17

Загальний вираз таблиці дозволяє чітко вказати псевдоніми не тільки для CTE, але і для його стовпців.

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

Це відрізняється від прикладу @ dezso тим, що він не використовується col AS aliasдля кожного кола зі SELECTсписку; він псевдоніми імен стовпців у псевдонімі таблиці CTE.

Я використовував VALUESвираз як підзапит, але ви можете використовувати SELECTвсе, що завгодно; справа в тому, що будь-які псевдоніми стовпців надані або припущені в підзапиті, можуть бути замінені у визначенні CTE, вказавши список імен стовпців.

Те ж саме можна зробити і в підзапиті, знову ж таки замість використання AS alias:

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

Це не працює ROWбезпосередньо з виразом; ви можете віддати лише ROWконкретний тип, ви не можете його псевдоніму.

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

Чи є різниця (крім стилю та / або читабельності) між нашими рішеннями (використання, ефективність тощо)?
dezso

@dezso Ні, і я, мабуть, повинен був щойно опублікувати коментар. Вибачте.
Крейг Рінгер

Я думаю, що це нормально. Я навіть схвалив вашу відповідь, коли вона містить корисну інформацію, яка у мене немає.
dezso

Чи є синтаксис для динамічного отримання псевдонімів стовпців? Я витягую із схеми EAV (значення атрибуту сутності), де потрібні імена ключів також вибираються зі стовпця attribute.name.
Кріс

@Chris Вам знадобляться більш досконалі функції json у 9.4.
Крейг Рінгер

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

зробить те, що ви хочете, без будь-якого впливу на ефективність (і не надто багатослівний):

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

4
Ця відповідь - дорогоцінний камінь.
тифон

Дякую, що ти врятував мій день, шкода, це не наводиться приклад в PostgreSQL API. Я знав, що це можливо
jlandercy

9

Ви можете зробити щось подібне:

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

(Звичайно, те саме можна досягти і з

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

але я знайшов колишнього більш читальним.)

У WITHчастині ви можете побудувати ряди будь-якої структури на льоту.


Щоб об'єднати non-jsonb з jsonb :: SELECT row_to_json (r. *) FROM (SELECT c1, c2 :: jsonb FROM us_ca_monterey_aoc.test) як r
Ендрю Скотт Еванс

9

Можна використовувати 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;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.