Отдельные значения ключа json в Mysql

У меня есть эта таблица mysql, в которой есть столбец, содержащий json со случайными ключами/значениями. Используя приведенный ниже запрос, я могу получить ключи/значения для всех идентификаторов, но, как вы можете видеть; он содержит повторяющиеся пакеты.

CREATE TABLE `my_table` (
  `package` mediumtext NOT NULL,
  `id` varchar(255) NOT NULL,
  `time` timestamp NOT NULL DEFAULT current_timestamp(),
  KEY `id` (`id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb3
INSERT INTO my_table (id, time, package) VALUES
    ('myhost', '2022-05-08 09:00:00', '{"acl": "2.3.1-1", "apparmor": "2.0.4-2ubuntu2", "at": "3.2.5-1ubuntu1"}'),
    ('myhost', '2022-05-09 09:00:00', '{"acl": "2.3.1-1", "apparmor": "2.0.4-2ubuntu2", "at": "3.2.5-1ubuntu1"}'),
    ('myhost', '2022-05-10 09:00:00', '{"acl": "3.4.5-6", "apparmor": "2.0.4-2ubuntu2", "at": "3.2.5-1ubuntu1"}'),
    ('host123', '2022-05-10 09:00:00', '{"httpd": "2.4.6-97-el7.centos.5", "kpartx": "0.4.9-135.el7_9", "libcap": "2.22-11.el7"}');
select id, time, package from my_table;
+---------+---------------------+------------------------------------------------------------------------------------------+
| id      | time                | package                                                                                  |
+---------+---------------------+------------------------------------------------------------------------------------------+
| myhost  | 2022-05-08 09:00:00 | {"acl": "2.3.1-1", "apparmor": "2.0.4-2ubuntu2", "at": "3.2.5-1ubuntu1"}                 |
| myhost  | 2022-05-09 09:00:00 | {"acl": "2.3.1-1", "apparmor": "2.0.4-2ubuntu2", "at": "3.2.5-1ubuntu1"}                 |
| myhost  | 2022-05-10 09:00:00 | {"acl": "3.4.5-6", "apparmor": "2.0.4-2ubuntu2", "at": "3.2.5-1ubuntu1"}                 |
| host123 | 2022-05-10 09:00:00 | {"httpd": "2.4.6-97-el7.centos.5", "kpartx": "0.4.9-135.el7_9", "libcap": "2.22-11.el7"} |
+---------+---------------------+------------------------------------------------------------------------------------------+
SELECT     id,time,pkg,Json_unquote(Json_extract(package, Concat('$.', pkg))) AS version
FROM       my_table
CROSS JOIN json_table(Json_keys(package,'$'), '$[*]' columns (pkg text path '$')) j
ORDER BY   pkg;
+---------+---------------------+----------+-----------------------+
| id      | time                | pkg      | version               |
+---------+---------------------+----------+-----------------------+
| myhost  | 2022-05-08 09:00:00 | acl      | 2.3.1-1               |
| myhost  | 2022-05-09 09:00:00 | acl      | 2.3.1-1               |
| myhost  | 2022-05-10 09:00:00 | acl      | 3.4.5-6               |
| myhost  | 2022-05-08 09:00:00 | apparmor | 2.0.4-2ubuntu2        |
| myhost  | 2022-05-09 09:00:00 | apparmor | 2.0.4-2ubuntu2        |
| myhost  | 2022-05-10 09:00:00 | apparmor | 2.0.4-2ubuntu2        |
| myhost  | 2022-05-08 09:00:00 | at       | 3.2.5-1ubuntu1        |
| myhost  | 2022-05-09 09:00:00 | at       | 3.2.5-1ubuntu1        |
| myhost  | 2022-05-10 09:00:00 | at       | 3.2.5-1ubuntu1        |
| host123 | 2022-05-10 09:00:00 | httpd    | 2.4.6-97-el7.centos.5 |
| host123 | 2022-05-10 09:00:00 | kpartx   | 0.4.9-135.el7_9       |
| host123 | 2022-05-10 09:00:00 | libcap   | 2.22-11.el7           |
+---------+---------------------+----------+-----------------------+

Как настроить запрос, чтобы он отфильтровывал повторяющиеся пакеты? Я хочу сохранить только 1 строку pkg + version на id, отсортированную по time:

+---------+---------------------+----------+-----------------------+
| id      | time                | pkg      | version               |
+---------+---------------------+----------+-----------------------+
| myhost  | 2022-05-10 09:00:00 | acl      | 3.4.5-6               |
| myhost  | 2022-05-10 09:00:00 | apparmor | 2.0.4-2ubuntu2        |
| myhost  | 2022-05-10 09:00:00 | at       | 3.2.5-1ubuntu1        |
| host123 | 2022-05-10 09:00:00 | httpd    | 2.4.6-97-el7.centos.5 |
| host123 | 2022-05-10 09:00:00 | kpartx   | 0.4.9-135.el7_9       |
| host123 | 2022-05-10 09:00:00 | libcap   | 2.22-11.el7           |
+---------+---------------------+----------+-----------------------+
Освоение архитектуры микросервисов с 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
0
26
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Вы можете попробовать использовать оконную функцию ROW_NUMBER с подзапросом, чтобы получить наименьшие значения для каждого id и pkg.

Запрос №1

SELECT id,time,pkg,version
FROM (
 SELECT     id,time,pkg,Json_unquote(Json_extract(package, Concat('$.', pkg))) AS version,
            ROW_NUMBER() OVER(PARTITION BY id,pkg ORDER BY time DESC,Json_unquote(Json_extract(package, Concat('$.', pkg)))) rn
 FROM       my_table
 CROSS JOIN json_table(Json_keys(package,'$'), '$[*]' columns (pkg text path '$')) j
) t1
WHERE rn = 1;
я бывремяупаковкаверсия
хост1232022-05-10 09:00:00httpd2.4.6-97-el7.centos.5
хост1232022-05-10 09:00:00kpartx0.4.9-135.el7_9
хост1232022-05-10 09:00:00libcap2.22-11.эл7
мой хозяин2022-05-10 09:00:00acl3.4.5-6
мой хозяин2022-05-10 09:00:00одежда2.0.4-2убунту2
мой хозяин2022-05-10 09:00:00в3.2.5-1убунту1

Просмотр на скрипте БД

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