How use JSON_ARRAYAGG in JSON_OBJECT without escaping content

Viewed 2966

.Hello,

I have a SQL query that returns a JSON array. I want to simplify it using the native JSON functions of mysql/mariadb.

The problem is that it escapes me the sub-array.I think the sub-request is analysed as a string of characters, But I haven't found a way and I don't know if it's possible to make mariadb understand that it's an array.

SELECT JSON_ARRAYAGG(
    JSON_OBJECT(
        'uuid', UuidFromBin(staff.uuid),
        'username', staff.username,
        'name', staff.name,
        'surname', staff.surname,
        'skills', (
            SELECT JSON_ARRAYAGG(
                JSON_OBJECT(
                    'uuid', UuidFromBin(s.uuid),
                    'name', s.name,
                    'shortName', s.short_name,
                    'description', s.description
                )
            )
            FROM staff_skills
            JOIN skills s ON s.id = skill_id
            WHERE staff_skills.staff_id = events_staff.staff_id
        )
    )
)
FROM events_staff
JOIN staff ON staff.id = staff_id
LEFT JOIN skills s ON s.id = events_staff.skill_id
WHERE event_id = 3

give

[
    {
        "uuid": "78edbe24-6e30-11ea-b47e-0242ac120003",
        "username": "xxx",
        "name": "xxx",
        "surname": "xxx",
        "skills": "[{\"uuid\": \"78efb999-6e30-11ea-b47e-0242ac120003\", \"name\": \"skillName\", \"shortName\": \"skillShortName\", \"description\": null},{\"uuid\": \"78efca7e-6e30-11ea-b47e-0242ac120003\", \"name\": \"Permis B\", \"shortName\": \"Perm. B\", \"description\": null}]"
    }
]

My old query work fine but is unreadeble :

SELECT CONCAT(
    '[',
        GROUP_CONCAT(
            CONCAT(
                '{',
                    '"uuid":"', UuidFromBin(staff.uuid),
                    '", "username":"', staff.username,
                    '", "name":"', staff.name,
                    '", "surname":"', staff.surname,
                    '", "skills":[',
                        IFNULL(
                            (
                                SELECT GROUP_CONCAT(
                                    CONCAT(
                                        '{"uuid":"', UuidFromBin(s.uuid), '", "name":"', s.name, '", "shortName":"', s.short_name, '"',
                                                    IFNULL(
                                            CONCAT(
                                                ', "description":"', s.description, '"'
                                            ),
                                            ''
                                        ),
                                        '}'
                                    ) SEPARATOR ', '
                                ) FROM staff_skills JOIN skills s ON s.id = skill_id WHERE staff_skills.staff_id = events_staff.staff_id
                            ),
                            ''
                        ),
                    ']',
                '}'
            ) SEPARATOR ', '
        ),
    ']'
)                
FROM events_staff
JOIN staff ON staff.id = staff_id
LEFT JOIN skills s ON s.id = events_staff.skill_id
WHERE event_id = 3

which give

[
   {
      "uuid":"78edbe24-6e30-11ea-b47e-0242ac120003",
      "username":"vlortet",
      "name":"vlortet",
      "surname":"Lortet",
      "skills":[
         {
            "uuid":"78efb999-6e30-11ea-b47e-0242ac120003",
            "name":"Premiers Secours en Équipe de Niveau 2",
            "shortName":"PSE2"
         },
         {
            "uuid":"78efca7e-6e30-11ea-b47e-0242ac120003",
            "name":"Permis B",
            "shortName":"Perm. B"
         }
      ]
   }
]

Thanks for reading :)


EDIT : I finnaly find a "bad" way. I use JSON_EXTRACT to convert the string to JSON... So we have several conversions. JSON > STRING > JSON...

SELECT JSON_ARRAYAGG(
    JSON_OBJECT(
        'uuid', UuidFromBin(staff.uuid),
        'username', staff.username,
        'name', staff.name,
        'surname', staff.surname,
        'skills', JSON_EXTRACT(
            (SELECT JSON_ARRAYAGG(
                JSON_OBJECT(
                    'uuid', UuidFromBin(s.uuid),
                    'name', s.name,
                    'shortName', s.short_name,
                    'description', s.description
                )
            )
            FROM staff_skills
            JOIN skills s ON s.id = skill_id
            WHERE staff_skills.staff_id = events_staff.staff_id),
            '$'
        )
    )
)
FROM events_staff
JOIN staff ON staff.id = staff_id
LEFT JOIN skills s ON s.id = events_staff.skill_id
WHERE event_id = 3
0 Answers
Related