JSON 데이터 생성
SQL 함수를 사용하여 관계형 테이블에서 형식화된 JSON 데이터를 생성할 수 있습니다.
JSON을 생성하기 위해 관계형 데이터에 대해 작업할 것입니다. 두 개의 테이블에 있는 데이터로 시작합니다. 하나는 기본 직원 데이터를 포함합니다. 다른 하나는 계정 정보를 포함합니다. 여기에 표시된 대로 작성되고 채워집니다.
create table empdata (id int,
last_name varchar(10),
first_name varchar(10),
office_number varchar(10),
work_phone varchar(20),
home_phone varchar(20));
create table emp_account (id int,
account varchar(20));
insert into empdata values (901, 'Doe', 'John', 'E-334', '555-7242', '555-3762');
insert into emp_account values (901, '36232'), (901, '73263');
insert into empdata values (902, 'Pan', 'Peter', 'E-216', '555-8925', null);
insert into emp_account values (902, '76232'), (902, '72963');
insert into empdata values (903, 'Jones', 'Mary', 'E-739', '555-4311', '555-6312');
insert into empdata values (904, 'Smith', 'Sally', null, null, null);
{"id":901, "name" : { "first":"John", "last":"Doe" }, "office" : "E-334",
"phones" : [ { "type":"home", "number":"555-3762" },
{ "type":"work", "number":"555-7242" } ],
"accounts" : [ { "number":"36232"}, { "number":"73263"}] }
{"id":902, "name" : { "first":"Peter", "last":"Pan" }, "office" : "E-216",
"phones" : [ { "type":"work", "number":"555-8925" } ],
"accounts" : [ { "number":"76232"}, {"number":"72963"}] }
{"id":903, "name" : { "first":"Mary", "last":"Jones" }, "office" : "E-739",
"phones" : [ { "type":"home", "number":"555-6312" },
{ "type":"work", "number":"555-4311" } ], }
{"id":904, "name" : { "first":"Sally", "last":"Smith" } }기본 JSON 오브젝트 빌드
간단한 예제부터 시작하여 기본 JSON 오브젝트를 얼마나 쉽게 생성할 수 있는지 살펴보겠습니다.
select json_object ('id' value id,
'name' value last_name,
'office' value office_number)
from empdata;
{"id":901,"name":"Doe","office":"E-334"}
{"id":902,"name":"Pan","office":"E-216"}
{"id":903,"name":"Jones","office":"E-739"}
{"id":904,"name":"Smith","office":null}select json_object ('id' value id,
'name' value last_name,
'office' value office_number
absent on null)
from empdata;이제 904에 대한 office 값이 없습니다.{"id":901,"name":"Doe","office":"E-334"}
{"id":902,"name":"Pan","office":"E-216"}
{"id":903,"name":"Jones","office":"E-739"}
{"id":904,"name":"Smith"}JSON 오브젝트 중첩
select json_object ('first' value first_name,
'last' value last_name)
from empdata;이 쿼리의 결과는 다음과 같습니다.{"first":"John","last":"Doe"}
{"first":"Peter","last":"Pan"}
{"first":"Mary","last":"Jones"}
{"first":"Sally","last":"Smith"}select json_object ('id' value id,
'name' value json_object ( 'first' value first_name,
'last' value last_name),
'office' value office_number
absent on null)
from empdata;{"id":901,"name":{"first":"John","last":"Doe"},"office":"E-334"}
{"id":902,"name":{"first":"Peter","last":"Pan"},"office":"E-216"}
{"id":903,"name":{"first":"Mary","last":"Jones"},"office":"E-739"}
{"id":904,"name":{"first":"Sally","last":"Smith"}}JSON 배열 빌드
select json_array
(case when home_phone is not null then
json_object('type' value 'home',
'number' value home_phone) end,
case when work_phone is not null then
json_object('type' value 'work',
'number' value work_phone) end
)
from empdata;결과는 다음과 같습니다. 각 항목의 출력은 전체 결과를 표시하기 위해 두 행으로 구분됩니다.["{\"type\":\"home\",\"number\":\"555-3762\"}",
"{\"type\":\"work\",\"number\":\"555-7242\"}"]
["{\"type\":\"work\",\"number\":\"555-8925\"}"]
["{\"type\":\"home\",\"number\":\"555-6312\"}",
"{\"type\":\"work\",\"number\":\"555-4311\"}"]
[]이는 예상치 못한 결과입니다. 결과에 이러한 모든 추가 \ 문자가 포함되는 이유는 무엇입니까? 이는 일반 문자 데이터 처리와 이미 JSON으로 형식화된 문자 데이터 간의 차이를 보여줍니다. JSON_ARRAY (또는 JSON 발행 함수 중 하나) 가 해당 인수를 보는 경우 인수가 다른 JSON 함수의 직접 결과인 경우를 인식합니다. 이 경우 문자열은 이미 형식화된 JSON 데이터로 해석됩니다. 이는 함수가 문자열의 특수 문자를 이스케이프하지 않음을 의미합니다. 인수가 JSON 함수의 직접 결과가 아닌 경우에는 비JSON 문자 데이터로 해석되며 값에 대해 이스케이프 처리가 수행됩니다. 이 예에서는 CASE 표현식에 JSON_OBJECT를 임베드했으므로 문자열이 이미 형식화된 JSON이라는 사실을 알 수 없습니다. 이러한 원하지 않는 이스케이프 시퀀스를 방지하려면 FORMAT JSON절을 사용하여 인수가 이미 JSON임을 JSON_ARRAY에 명시적으로 알려야 합니다.
select json_array
(case when home_phone is not null then
json_object('type' value 'home',
'number' value home_phone) end
format json,
case when work_phone is not null then
json_object('type' value 'work',
'number' value work_phone) end
format json)
from empdata;이제 결과는 다음과 같습니다.[{"type":"home","number":"555-3762"},{"type":"work","number":"555-7242"}]
[{"type":"work","number":"555-8925"}]
[{"type":"home","number":"555-6312"},{"type":"work","number":"555-4311"}]
[]select json_object ('id' value id,
'name' value json_object ( 'first' value first_name,
'last' value last_name),
'office' value office_number,
'phones' value json_array
(case when home_phone is not null then
json_object('type' value 'home',
'number' value home_phone
) end format json,
case when work_phone is not null then
json_object('type' value 'work',
'number' value work_phone
) end format json)
absent on null)
from empdata;다음이 리턴됩니다.{"id":901,"name":{"first":"John","last":"Doe"},"office":"E-334",
"phones":[{"type":"home","number":"555-3762"},{"type":"work","number":"555-7242"}]}
{"id":902,"name":{"first":"Peter","last":"Pan"},"office":"E-216",
"phones":[{"type":"work","number":"555-8925"}]}
{"id":903,"name":{"first":"Mary","last":"Jones"},"office":"E-739",
"phones":[{"type":"home","number":"555-6312"},{"type":"work","number":"555-4311"}]}
{"id":904,"name":{"first":"Sally","last":"Smith"},
"phones":[]}여러 데이터 행에서 배열 빌드
select json_array(json_object('number' value account))
from emp_account;이 쿼리의 결과는 다음과 같습니다.[{"number":"36232"}]
[{"number":"73263"}]
[{"number":"76232"}]
[{"number":"72963"}]각 계정 번호에 대해 하나의 배열이 생성되었습니다. 각 ID 값에 대해 하나의 배열이 필요합니다. 이 경우 단일 ID 값에 대한 모든 number JSON 오브젝트를 단일 배열로 집계해야 합니다.select json_arrayagg(json_object('number' value account))
from emp_account group by id;JSON_ARRAYAGG는 데이터 그룹에서 작동하는 집계 함수입니다. 이 경우 ID 열을 그룹화합니다. ID 의 각 계정은 오브젝트를 생성한 후 모든 해당 오브젝트를 단일 배열로 집계합니다. 이 조회는 두 개의 행만 리턴합니다. 각 ID 값에 대해 하나씩 정확하게 찾은 행을 리턴합니다.[{"number":"36232"},{"number":"73263"}]
[{"number":"76232"},{"number":"72963"}]select json_object ('id' value id,
'name' value json_object ( 'first' value first_name,
'last' value last_name),
'office' value office_number,
'phones' value json_array
(case when home_phone is not null then
json_object('type' value 'home',
'number' value home_phone
) end format json,
case when work_phone is not null then
json_object('type' value 'work',
'number' value work_phone
) end format json),
'accounts' value (select json_arrayagg(
json_object('number' value account))
from emp_account a
where a.id = e.id group by id) format json
absent on null)
from empdata e;이제 우리는 최종 결과에 도착했다.{"id":901,"name":{"first":"John","last":"Doe"},"office":"E-334",
"phones":[{"type":"home","number":"555-3762"},
{"type":"work","number":"555-7242"}],
"accounts":[{"number":"36232"},{"number":"73263"}]}
{"id":902,"name":{"first":"Peter","last":"Pan"},"office":"E-216",
"phones":[{"type":"work","number":"555-8925"}],
"accounts":[{"number":"76232"},{"number":"72963"}]}
{"id":903,"name":{"first":"Mary","last":"Jones"},"office":"E-739",
"phones":[{"type":"home","number":"555-6312"},
{"type":"work","number":"555-4311"}]}
{"id":904,"name":{"first":"Sally","last":"Smith"},"phones":[]}JSON을 하나의 오브젝트에 결합
select json_object('employees' value json_arrayagg(
json_object ('id' value id,
'name' value json_object ( 'first' value first_name,
'last' value last_name),
'office' value office_number,
'phones' value json_array
(case when home_phone is not null then
json_object('type' value 'home',
'number' value home_phone
) end format json,
case when work_phone is not null then
json_object('type' value 'work',
'number' value work_phone
) end format json),
'accounts' value (select json_arrayagg(
json_object('number' value account))
from emp_account a
where a.id = e.id group by id) format json
absent on null)))
from empdata e;먼저 결과를 JSON_ARRAYAGG로 랩핑하여 직원 정보의 배열을 작성합니다. 그런 다음 JSON_OBJECT로 배열을 랩핑하여 최종 결과가 단일 JSON 오브젝트가 되도록 합니다. 이제 결과는 하나의 JSON 오브젝트입니다.{"employees":[
{"id":901,"name":{"first":"John","last":"Doe"},"office":"E-334",
"phones":[{"type":"home","number":"555-3762"},
{"type":"work","number":"555-7242"}],
"accounts":[{"number":"36232"},{"number":"73263"}]},
{"id":902,"name":{"first":"Peter","last":"Pan"},"office":"E-216",
"phones":[{"type":"work","number":"555-8925"}],
"accounts":[{"number":"76232"},{"number":"72963"}]},
{"id":903,"name":{"first":"Mary","last":"Jones"},"office":"E-739",
"phones":[{"type":"home","number":"555-6312"},
{"type":"work","number":"555-4311"}]},
{"id":904,"name":{"first":"Sally","last":"Smith"},"phones":[]}
]}결과 데이터 유형 설정
select json_object ('id' value id,
'name' value last_name,
'office' value office_number
returning varbinary(2000) format bson)
from empdata;공통 테이블 표현식을 사용하여 구별 값 집계
with sales_tmp(sales_person) as (
select distinct(sales_person) from sales),
region_tmp(region,sales_person) as (
select distinct region, sales_person from sales)
select json_object( key sales_person
value (select JSON_ARRAYAGG(region order by region)
from region_tmp r where r.sales_person = s.sales_person)
format json)
FROM sales_tmp s order by sales_person;샘플 테이블에서 다음 세 개의 행이 리턴됩니다.{"GOUNOT":["Manitoba","Ontario-North","Ontario-South","Quebec"]}
{"LEE":["Manitoba","Ontario-North","Ontario-South","Quebec"]}
{"LUCCHESSI":["Manitoba","Ontario-South","Quebec"]}with sales_tmp(sales_person) as (
select distinct(sales_person) from sales),
region_tmp(region,sales_person) as (
select distinct region, sales_person from sales)
select json_objectagg( key sales_person
value (select JSON_ARRAYAGG(region order by region)
from region_tmp r where r.sales_person = s.sales_person)
format json)
FROM sales_tmp s;이는 하나의 JSON 오브젝트를 포함하는 하나의 행을 리턴합니다. 쉽게 읽을 수 있도록 여기서는 여러 행으로 구분되어 있습니다.{"LEE":["Manitoba","Ontario-North","Ontario-South","Quebec"],
"GOUNOT":["Manitoba","Ontario-North","Ontario-South","Quebec"],
"LUCCHESSI":["Manitoba","Ontario-South","Quebec"]}