Вложенный JSON в MySQL с фильтрацией

Вот JSON, который у меня есть в таблице MySQL:

{
    "qmSubsegmentFlags": [
        {
            "text": "Accuracy",
            "id": 1,
            "children": [
                {
                    "text": "Mistranslation",
                    "id": 2,
                    "children": [
                        {
                            "text": "Terminology",
                            "id": 3
                        }
                    ]
                },
                {
                    "text": "Omission",
                    "id": 4
                },
                {
                    "text": "Addition",
                    "id": 5
                },
                {
                    "text": "Untranslated",
                    "id": 6
                }
            ]
        }
    ]
}

Итак, вы видите, идентификаторы и текст могут быть на разных уровнях. У меня есть только значение идентификатора, и я должен получить текст для этого с помощью SQL. Ниже путь JSON, который работает для первого уровня, но не для всех уровней. Он также не работает в MySQL, поскольку MySQL поддерживает только ограниченную фильтрацию.

$.qmSubsegmentFlags[?(@.id==1)].text

Небольшой SQL, который идет в правильном направлении, но тоже не решает проблему.

SELECT JSON_EXTRACT(t.qmSubsegmentFlags, '$.qmSubsegmentFlags[*].text') AS lqa FROM translate5.LEK_task AS t where id = 3719;

Раньше я был программистом, но после 4 лет управления проектами мои навыки умерли. Но мне нужно доказательство концепции до понедельника. Любая помощь будет здорово!

Готовы ли вы использовать для этого JSON? Было бы намного проще, если бы вы не использовали JSON (это утверждение применимо ко многим случаям использования JSON в MySQL).

Bill Karwin 10.02.2023 17:17

Также вы можете запустить этот запрос и сообщить, что он возвращает: SELECT VERSION();

Bill Karwin 10.02.2023 17:18

Вложенный JSON выглядит так в БД продукта, который мы используем. Это открытый исходный код, поэтому он не высечен на камне, но, скорее всего, его очень и очень трудно изменить. Версия 8.0.26

Remy 13.02.2023 08:55
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
1
3
72
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вот решение, протестированное на MySQL 8.0.32.

WITH RECURSIVE tree AS (
  SELECT j.id, j.text, j.children
  FROM LEK_task CROSS JOIN JSON_TABLE(
    JSON_EXTRACT(qmSubsegmentFlags, '$.qmSubsegmentFlags'),
    '$[*]' COLUMNS (
      text TEXT PATH '$.text',
      id INT PATH '$.id',
      children JSON PATH '$.children'
    )
  ) AS j
  WHERE LEK_task.id = 3719
  UNION ALL
  SELECT j.id, j.text, j.children
  FROM tree CROSS JOIN JSON_TABLE(
    children,
    '$[*]' COLUMNS(
      text TEXT PATH '$.text',
      id INT PATH '$.id',
      children JSON PATH '$.children'
    )
  ) AS j
)
SELECT id, text FROM tree;

Результат:

+------+----------------+
| id   | text           |
+------+----------------+
|    1 | Accuracy       |
|    2 | Mistranslation |
|    4 | Omission       |
|    5 | Addition       |
|    6 | Untranslated   |
|    3 | Terminology    |
+------+----------------+

Вы можете добавить WHERE id = 1 к последней строке запроса, чтобы получить строку для определенного идентификатора.

Другие вопросы по теме