GROUP_CONCAT для возврата массива объектов в отношениях многих ко многим - PullRequest
1 голос
/ 05 октября 2019

Я работаю над запросом mySQL для личного проекта. В настоящее время конечная цель состоит в том, чтобы запрос возвращал следующий json для каждого элемента:

{
    "id": 1,
    "designName": "Slender Man",
    "designNotes": "Rewrite the lapel component",
    "quantity": 3,
    "colors": [
        {
        "id": 4,
        "colorName": "black",
        "colorSwatch": "rgb (0,0,0)",
        "brandName": "caron simply soft",
        "yarnWeightId": {
              "weightNumber": 4,
              "weightName": "medium/worst weight"
          }
        },{
        "id": 5,
        "colorName": "Off White",
        "colorSwatch": "rgb (255,255,255)",
        "brandName": "caron simply soft",
        "yarnWeightId": {
              "weightNumber": 4,
              "weightName": "medium/worst weight"
          }
        }
    ]
}

Моя последняя попытка:

SELECT 
    d.id,
    d.designName,
    d.designNotes,
    d.quantity,
    d.isDeleted,
    GROUP_CONCAT(
        JSON_OBJECT(
            c.colorName,
            c.colorSwatch,
            c.brandName,
            yw.weightNumber,
            yw.weightName
        )
    ) AS colorsUsed
FROM designs AS d
    INNER JOIN design_colors AS dc 
        ON dc.designId = d.id
    INNER JOIN colors AS c 
        ON dc.colorId = c.id
    INNER JOIN yarnweights AS yw 
        ON c.yarnWeightId = yw.id
GROUP BY d.id
;

, что приводит к внутренней ошибке сервера,Тестирование с помощью более простого запроса проходит нормально, поэтому я сузил его до самого запроса, являющегося проблемой.

Приведенный ниже запрос сбил меня с толку:

SELECT 
    d.id,
    d.designName,
    d.designNotes,
    d.quantity,
    d.isDeleted,
    GROUP_CONCAT(
        DISTINCT c.id
        GROUP BY c.id
    ) AS colorsUsed
FROM designs AS d
    INNER JOIN design_colors AS dc 
        ON dc.designId = d.id
    INNER JOIN colors AS c 
        ON dc.colorId = c.id
    INNER JOIN yarnweights AS yw 
        ON c.yarnWeightId = yw.id
GROUP BY
    d.id

Он вернул объекты, подобные этому:

{
    "id": 3,
    "designName": "Slenderman",
    "designNotes": null,
    "quantity": 0,
    "isDeleted": 0,
    "colorsUsed": "4,5"
}

Но пока я получаю идентификаторы всех colorsUsed Iне получайте их в массиве, не говоря уже о массиве объектов, которые мне там нужны. Я чувствую, что GROUP_CONCAT не является правильным решением для этого, или, по крайней мере, я не правильно его использую, но это то, что возникает, когда я пытаюсь найти решение. Точка в правильном направлении, чтобы продолжать искать, была бы также полезна.


Моя база данных имеет следующую структуру: [диаграмма базы данных] [https://i.stack.imgur.com/lxsvv.png]

1 Ответ

0 голосов
/ 05 октября 2019

Вместо использования функции конкатенации строк, такой как GROUP_CONCAT(), вы можете сгенерировать действительный объект JSON, используя функции MySQL JSON. JSON_OBJECT() может использоваться для создания объектов, а JSON_ARRAYAGG() - агрегатная функция, которая генерирует массивы JSON.

Сначала давайте начнем с запроса, который возвращает все необходимые столбцы:

SELECT 
    d.id,
    d.designName,
    d.designNotes,
    d.quantity,
    c.id,
    c.colorName,
    c.colorSwatch,
    c.brandName
    y.weightNumber,
    y.weightName
FROM 
    designs AS d
    INNER JOIN design_colors AS dc ON dc.designId = d.id
    INNER JOIN colors AS c ON dc.colorId = c.id
    INNER JOIN yarnweights AS y ON c.yarnWeightId = y.id

Теперь мы можем включить агрегирование и использовать функции JSON для генерации ожидаемого набора результатов:

SELECT JSON_OBJECT(
    'id', d.id,
    'designName', d.designName,
    'designNotes', d.designNotes,
    'quantity', d.quantity,
    'colors', JSON_ARRAYAGG(
        JSON_OBJECT(
            'id', c.id,
            'colorName', c.colorName,
            'colorSwatch', c.colorSwatch,
            'brandName', c.brandName
            'yarnWeightId', JSON_OBJECT(
                'weightNumber', y.weightNumber,
                'weightName', y.weightName
            )
        )
    ) AS myjson
FROM 
    designs AS d
    INNER JOIN design_colors AS dc ON dc.designId = d.id
    INNER JOIN colors AS c ON dc.colorId = c.id
    INNER JOIN yarnweights AS y ON c.yarnWeightId = y.id
GROUP BY
    d.id,
    d.designName,
    d.designNotes,
    d.quantity

Возвращает набор результатов с уникальным столбцом, где каждая запись содержит ожидаемый объект JSON.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...