I have an Oracle 19 database with a JSON aggregated array which I need to cut off and repeat after a set number of rows, for example:
[{"personId": "13274614","surname": "SMITH"},{"personId": "13275037","surname": "JONES"}]
[{"personId": "13275038","surname": "THOMAS"},{"personId": "13275039","surname": "BAKER"}]
...etc. Here's some basic SQL to illustrate how my current dataset is put together:
SELECT
json_arrayagg(json_object('personId' VALUE person.id,
'surname' VALUE person.surname
)
RETURNING CLOB) as customer_json
FROM
person
I need to push customer data to an API endpoint. Pushing 1 customer record at a time is not performant, but the entire dataset is in the millions so cannot fit in a single array, therefore I need to, if possible, achieve the best of both worlds - 200 customer records in an array, which then ends and the next row starts a fresh array with the next 200 customers.
I have searched and found some mentions of a LIMIT function, but have not been able to successfully apply this.
Does anyone have an idea on how I can achieve this?
CodePudding user response:
From Oracle 12, you can use ORDER BY ... OFFSET ... FETCH NEXT ...
to limit the number of rows inside a sub-query:
SELECT json_arrayagg(
json_object(
'personId' VALUE id,
'surname' VALUE surname
)
RETURNING CLOB
) as customer_json
FROM (
SELECT id, surname
FROM person
ORDER BY id
OFFSET 0 ROWS
FETCH NEXT 200 ROWS ONLY
)
Before Oracle 12, you can use the ROW_NUMBER
analytic function:
SELECT json_arrayagg(
json_object(
'personId' VALUE id,
'surname' VALUE surname
)
RETURNING CLOB
) as customer_json
FROM (
SELECT id,
surname,
ROW_NUMBER() OVER (ORDER BY id) AS rn
FROM person
)
WHERE rn BETWEEN 1 AND 200;
If you want all the rows in 200 row groups then:
SELECT json_arrayagg(
json_object(
'personId' VALUE id,
'surname' VALUE surname
)
RETURNING CLOB
) as customer_json
FROM (
SELECT id,
surname,
CEIL(ROW_NUMBER() OVER (ORDER BY id)/200) AS grp
FROM person
)
GROUP BY grp;