PostgreSQL은 JSON 배열로 결과 집합을 반환합니까?
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
SELECT json_agg(t) FROM t
객체의 JSON 배열 및
SELECT
json_build_object(
'a', json_agg(t.a),
'b', json_agg(t.b)
)
FROM t
배열의 JSON 객체에 대해.
개체 목록
이 섹션에서는 각 행이 단일 객체로 변환되는 JSON 객체 배열을 생성하는 방법을 설명합니다. 결과는 다음과 같습니다.
[{"a":1,"b":"value1"},{"a":2,"b":"value2"},{"a":3,"b":"value3"}]
9.3 이상
이 json_agg
함수는이 결과를 즉시 생성합니다. 입력을 JSON으로 변환하고 배열로 집계하는 방법을 자동으로 파악합니다.
SELECT json_agg(t) FROM t
이 더되는 jsonb
버전 (9.4에서 소개하지 않음) json_agg
. 행을 배열로 집계 한 다음 변환 할 수 있습니다.
SELECT to_jsonb(array_agg(t)) FROM t
또는 json_agg
캐스트와 결합 :
SELECT json_agg(t)::jsonb FROM t
내 테스트에 따르면 먼저 어레이로 집계하는 것이 조금 더 빠릅니다. 캐스트가 전체 JSON 결과를 구문 분석해야하기 때문이라고 생각합니다.
9.2
9.2에는 json_agg
또는 to_json
함수가 없으므로 이전 버전을 사용해야합니다 array_to_json
.
SELECT array_to_json(array_agg(t)) FROM t
선택적으로 row_to_json
쿼리에 호출을 포함 할 수 있습니다 .
SELECT array_to_json(array_agg(row_to_json(t))) FROM t
이렇게하면 각 행이 JSON 개체로 변환되고 JSON 개체가 배열로 집계 된 다음 배열이 JSON 배열로 변환됩니다.
나는 둘 사이의 중요한 성능 차이를 식별 할 수 없었습니다.
목록의 대상
이 섹션에서는 각 키가 테이블의 열이고 각 값이 열 값의 배열 인 JSON 개체를 생성하는 방법을 설명합니다. 다음과 같은 결과입니다.
{"a":[1,2,3], "b":["value1","value2","value3"]}
9.5 이상
다음 json_build_object
기능을 활용할 수 있습니다 .
SELECT
json_build_object(
'a', json_agg(t.a),
'b', json_agg(t.b)
)
FROM t
열을 집계하여 단일 행을 만든 다음이를 객체로 변환 할 수도 있습니다.
SELECT to_json(r)
FROM (
SELECT
json_agg(t.a) AS a,
json_agg(t.b) AS b
FROM t
) r
Note that aliasing the arrays is absolutely required to ensure that the object has the desired names.
Which one is clearer is a matter of opinion. If using the json_build_object
function, I highly recommend putting one key/value pair on a line to improve readability.
You could also use array_agg
in place of json_agg
, but my testing indicates that json_agg
is slightly faster.
There is no jsonb
version of the json_build_object
function. You can aggregate into a single row and convert:
SELECT to_jsonb(r)
FROM (
SELECT
array_agg(t.a) AS a,
array_agg(t.b) AS b
FROM t
) r
Unlike the other queries for this kind of result, array_agg
seems to be a little faster when using to_jsonb
. I suspect this is due to overhead parsing and validating the JSON result of json_agg
.
Or you can use an explicit cast:
SELECT
json_build_object(
'a', json_agg(t.a),
'b', json_agg(t.b)
)::jsonb
FROM t
The to_jsonb
version allows you to avoid the cast and is faster, according to my testing; again, I suspect this is due to overhead of parsing and validating the result.
9.4 and 9.3
The json_build_object
function was new to 9.5, so you have to aggregate and convert to an object in previous versions:
SELECT to_json(r)
FROM (
SELECT
json_agg(t.a) AS a,
json_agg(t.b) AS b
FROM t
) r
or
SELECT to_jsonb(r)
FROM (
SELECT
array_agg(t.a) AS a,
array_agg(t.b) AS b
FROM t
) r
depending on whether you want json
or jsonb
.
(9.3 does not have jsonb
.)
9.2
In 9.2, not even to_json
exists. You must use row_to_json
:
SELECT row_to_json(r)
FROM (
SELECT
array_agg(t.a) AS a,
array_agg(t.b) AS b
FROM t
) r
Documentation
Find the documentation for the JSON functions in JSON functions.
json_agg
is on the aggregate functions page.
Design
If performance is important, ensure you benchmark your queries against your own schema and data, rather than trust my testing.
Whether it's a good design or not really depends on your specific application. In terms of maintainability, I don't see any particular problem. It simplifies your app code and means there's less to maintain in that portion of the app. If PG can give you exactly the result you need out of the box, the only reason I can think of to not use it would be performance considerations. Don't reinvent the wheel and all.
Nulls
Aggregate functions typically give back NULL
when they operate over zero rows. If this is a possibility, you might want to use COALESCE
to avoid them. A couple of examples:
SELECT COALESCE(json_agg(t), '[]'::json) FROM t
Or
SELECT to_jsonb(COALESCE(array_agg(t), ARRAY[]::t[])) FROM t
Credit to Hannes Landeholm for pointing this out
Also if you want selected field from table and aggregated then as array .
SELECT json_agg(json_build_object('data_a',a,
'data_b',b,
)) from t;
The result will come .
[{'data_a':1,'data_b':'value1'}
{'data_a':2,'data_b':'value2'}]
참고 URL : https://stackoverflow.com/questions/24006291/postgresql-return-result-set-as-json-array
'program tip' 카테고리의 다른 글
UITextView에서 링크 클릭을 차단하는 방법은 무엇입니까? (0) | 2020.08.25 |
---|---|
Git은 새 하위 모듈을 초기화 / 동기화 / 업데이트하지 않습니다. (0) | 2020.08.25 |
권한이 s3 인 경우 S3 버킷 용 ListObjects에 대한 AccessDenied : * (0) | 2020.08.25 |
내 네트워크의 다른 컴퓨터에서 내 IIS 호스팅 사이트보기 (0) | 2020.08.25 |
암호를 서버 측으로 보내기 전에 해시해야합니까? (0) | 2020.08.25 |