Я хотел бы, чтобы PostgreSQL возвращал результат запроса в виде одного массива JSON. Дано
create table t (a int primary key, b text);
insert into t values (1, 'value1');
insert into t values (2, 'value2');
insert into t values (3, 'value3');
Хотелось бы что-то похожее на
[{"a":1,"b":"value1"},{"a":2,"b":"value2"},{"a":3,"b":"value3"}]
или
{"a":[1,2,3], "b":["value1","value2","value3"]}
(на самом деле было бы полезнее знать оба). Я пробовал такие вещи, как
select row_to_json(row) from (select * from t) row;
select array_agg(row) from (select * from t) row;
select array_to_string(array_agg(row), '') from (select * from t) row;
И я чувствую, что близок, но на самом деле не там. Стоит ли искать другую документацию, кроме 9.15. Функции и операторы JSON ?
Кстати, я не совсем уверен в своей идее. Это обычное дизайнерское решение? Я думаю, что я мог бы, конечно, взять результат (например) первого из трех вышеупомянутых запросов и немного манипулировать им в приложении, прежде чем передавать его клиенту, но если PostgreSQL может напрямую создать конечный объект JSON, это было бы проще, потому что я до сих пор не включил в свое приложение какую-либо зависимость от какой-либо библиотеки JSON.
источник
Ответы:
TL; DR
для массива объектов JSON и
для объекта массивов JSON.
Список объектов
В этом разделе описывается, как сгенерировать массив объектов JSON, каждая строка которого преобразуется в один объект. Результат выглядит так:
9.3 и выше
json_agg
Функция производит этот результат из коробки. Он автоматически определяет, как преобразовать входные данные в JSON, и объединяет их в массив.Не существует
jsonb
(введено в 9.4) версииjson_agg
. Вы можете объединить строки в массив, а затем преобразовать их:или комбинировать
json_agg
с гипсом:Мое тестирование показывает, что сначала объединить их в массив немного быстрее. Я подозреваю, что это потому, что приведение должно анализировать весь результат JSON.
9,2
9.2 не имеет функций
json_agg
илиto_json
, поэтому вам нужно использовать старую версиюarray_to_json
:Вы можете дополнительно включить
row_to_json
вызов в запрос:Это преобразует каждую строку в объект JSON, объединяет объекты JSON в массив, а затем преобразует массив в массив JSON.
Я не смог заметить какой-либо значительной разницы в производительности между ними.
Объект списков
В этом разделе описывается, как сгенерировать объект JSON, где каждый ключ является столбцом в таблице, а каждое значение - массивом значений столбца. Результат выглядит так:
9.5 и выше
Мы можем использовать
json_build_object
функцию:Вы также можете агрегировать столбцы, создав одну строку, а затем преобразовать ее в объект:
Обратите внимание, что псевдонимы массивов абсолютно необходимы, чтобы гарантировать, что объект имеет желаемые имена.
Какой из них яснее - вопрос личного мнения. Если вы используете
json_build_object
функцию, я настоятельно рекомендую поместить одну пару ключ / значение в строку, чтобы улучшить читаемость.Вы также можете использовать
array_agg
вместоjson_agg
, но мое тестирование показывает, чтоjson_agg
это немного быстрее.Нет
jsonb
версииjson_build_object
функции. Вы можете объединить в одну строку и преобразовать:В отличие от других запросов для такого рода результатов,
array_agg
при использовании кажется немного быстрееto_jsonb
. Я подозреваю, что это связано с дополнительным анализом и проверкой результата JSONjson_agg
.Или вы можете использовать явное приведение:
to_jsonb
Версия позволяет избежать бросания и быстрее, по моему тестирования; опять же, я подозреваю, что это связано с накладными расходами на синтаксический анализ и проверку результата.9.4 и 9.3
Эта
json_build_object
функция была новой для 9.5, поэтому в предыдущих версиях вам нужно было агрегировать и преобразовывать в объект:или
в зависимости от того, хотите ли вы
json
илиjsonb
.(9.3 не имеет
jsonb
.)9,2
В 9.2 даже не
to_json
существует. Вы должны использоватьrow_to_json
:Документация
Найдите документацию по функциям JSON в функциях JSON .
json_agg
находится на странице агрегатных функций .дизайн
Если производительность важна, убедитесь, что вы сравниваете свои запросы со своей собственной схемой и данными, а не доверяете моему тестированию.
Хороший ли это дизайн или нет, на самом деле зависит от вашего конкретного приложения. В плане ремонтопригодности особых проблем не вижу. Это упрощает код вашего приложения и означает, что в этой части приложения меньше нужно поддерживать. Если PG может дать вам именно тот результат, который вам нужен, единственная причина, по которой я могу не использовать его, - это соображения производительности. Не изобретайте велосипед и все такое.
Нулевые
Агрегатные функции обычно возвращаются,
NULL
когда они работают над нулевыми строками. Если это возможно, вы можете использовать,COALESCE
чтобы избежать их. Пара примеров:Или
Кредит Ханнес Landeholm для указывая на это
источник
to_json
вместоrow_to_json
иarray_to_json
SELECT json_agg((column1, column2, ...)) FROM t
- обратите внимание на дополнительные скобки. Это может быть неочевидно «из коробки».Также, если вы хотите выбрать поле из таблицы и агрегировать его как массив.
Результат придет.
источник