1

I'm struggling trying to aggregate results in a table into a nested json.

this is the table:

+----+------+--------+------+------+-------+-----------+--------------+
| id | area | userId | game | step | score | completed | validAnswers |
+----+------+--------+------+------+-------+-----------+--------------+
| 1 | 2 | 21 | 7 | 53 | 10 | 0 | 0 |
| 2 | 2 | 37 | 7 | 53 | 0 | 0 | 0 |
| 3 | 2 | 21 | 7 | 53 | 10 | 0 | 0 |
| 4 | 2 | 37 | 7 | 53 | 10 | 0 | 0 |
...
| 37 | 3 | 21 | 7 | 57 | 80 | 1 | 8 |
| 38 | 2 | 21 | 8 | 56 | 80 | 1 | 8 |
| 39 | 2 | 21 | 7 | 58 | 100 | 1 | 10 |
| 40 | 2 | 21 | 7 | 59 | 50 | 1 | 5 |
+----+------+--------+------+------+-------+-----------+--------------+

I would like to create a view showing something like this:

+--------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| userId | completedSteps |
+--------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 21 | [{"area": 2, "games": [{"id": 7, "steps": [58, 59]},{"id":8,"steps":[15,16,17]}]},{"area": 3, "games": [{"id": 1, "steps": [34, 18]},{"id":4,"steps":[11,12,14]}]}] |
| 18 | [{"area": 2, "games": [{"id": 7, "steps": [58, 59]},{"id":8,"steps":[15,16,17]}]},{"area": 3, "games": [{"id": 1, "steps": [34, 18]},{"id":4,"steps":[11,12,14]}]}] |
| 23 | [{"area": 2, "games": [{"id": 7, "steps": [58, 59]},{"id":8,"steps":[15,16,17]}]},{"area": 3, "games": [{"id": 1, "steps": [34, 18]},{"id":4,"steps":[11,12,14]}]}] |
| 11 | [{"area": 2, "games": [{"id": 7, "steps": [58, 59]},{"id":8,"steps":[15,16,17]}]},{"area": 3, "games": [{"id": 1, "steps": [34, 18]},{"id":4,"steps":[11,12,14]}]}] |
+--------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+

grouping all games each with its steps into the area they belong. This is a dbfiddle I created.

I tried different approaches like beginning with

select userId, 
 json_arrayagg(
 select distinct area
 from scoreTable st2
 where st1.userId =st2.userId and
 st1.area=st2.area
 group by area
 ) as completedSteps
from scoreTable st1
where completed = 1
group by userId ;

which sorprisingly doesn't group by area, or

select userId,
 json_objectagg('areas',
 (select distinct area
 from scoreTable st2 
 where st1.userId =st2.userId
 group by area)) as completedSteps
from scoreTable st1
where completed = 1
group by userId ;

or many other attempts. I can get discrete area results like:

select area,
 json_object('games',json_object('id',game,'steps',JSON_ARRAYAGG(step))) as completedSteps
from scoreTable
where completed = 1
group by userId,area,game;
 

but whatever attempt tries to aggregate areas into array of objects fails. Could anybody help me undestad what am I missing?

UPDATE:

this is something closer to what I want to get:

select userId, json_arrayagg(json_object('completed',completed)) as completed
from (
select distinct userId, json_arrayagg(json_object('area',area,'games',completed)) as completed
from (
 select distinct userId,area, json_object('id',game,'steps',(json_arrayagg(step))) as completed
from scoreTable
where completed = 1 and userId = 21
group by area,game
) st1
group by userId, area
) st3
group by userId

but still doesn't groups games nesting them into area super object. keeping struggling..

asked Jul 8, 2022 at 8:27

1 Answer 1

1

this seems to be the actual solution

select userId, json_arrayagg(areas) as completedSteps
from (
 select distinct userId,
 json_object('area',area,'games',(json_arrayagg(games))) as areas
 from (
 select distinct userId,area,
 json_object('id',game,'steps',(json_arrayagg(step))) as games
 from scoreTable
 where completed = 1 
 group by area,game,userId
 ) st1
 group by userId, area) st2
group by userId;

even if I'm still investigating how to select distinct steps which are possibly duplicate

answered Jul 8, 2022 at 14:48

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.