SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 17.12.2021 19:29:23

LazY
_cмельчак
MySQL Authorized Developer and DBA
Зарегистрирован: 02.04.2007
Сообщений: 844

JSON: как посчитать min/max, сумму и другие агрегирующие значения

Внезапно я осознал, что не понимаю, как из поля типа JSON выбрать, например, наибольшее из значений.

Код:

CREATE TABLE test (
    i INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    j JSON
);

INSERT INTO test (j) VALUES
    ('[10, 20, 30]'),
    ('[100, 500]');

Код:

mysql> SELECT * FROM test;
+---+--------------+
| i | j            |
+---+--------------+
| 1 | [10, 20, 30] |
| 2 | [100, 500]   |
+---+--------------+

Как выглядит запрос, который для каждой записи выберет максимальное число из массивов в колонке j?

Неактивен

 

#2 17.12.2021 20:30:33

deadka
Администратор
Зарегистрирован: 14.11.2007
Сообщений: 2382

Re: JSON: как посчитать min/max, сумму и другие агрегирующие значения

LazY, полагаю, тебе сюда смотреть
https://dev.mysql.com/doc/refman/8.0/en … json-table


Зеленый свет для слабаков, долги отдают только трусы, тру гики работают только в консоли...

Неактивен

 

#3 18.12.2021 11:17:33

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3872

Re: JSON: как посчитать min/max, сумму и другие агрегирующие значения

Похоже, что такого типа функции в MySQL еще не поддерживаются. Задача похожа на вычисление суммы элементов массива JSON. Для этого предлагают написать хранимую функцию:
https://stackoverflow.com/a/45297362
Функция для MAX полностью аналогична.

Неактивен

 

#4 31.01.2022 19:21:12

LazY
_cмельчак
MySQL Authorized Developer and DBA
Зарегистрирован: 02.04.2007
Сообщений: 844

Re: JSON: как посчитать min/max, сумму и другие агрегирующие значения

Единственное решение здесь действительно через JSON_TABLE(), как все и говорили.

На мой взгляд, серьезная недоработка со стороны разработчиков MySQL:

1. Нужно добавлять в запрос не только дополнительную таблицу, но еще и группировку. Причем сходу не разберешься, как такой запрос надо писать, потому что JOIN тут необычный, а специально мутировавший для конкретно этого случая.

2. Таким образом нельзя построить виртуальные колонки и, как следствие, индексы по ним. Если нужно по такому сортировать, придется гонять по всей таблице hmm

Оставлю тут наглядный пример. Может, кому пригодится:


# 1. Создаём таблицу:
CREATE TABLE test (
    id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    data JSON
);

# 2. Вставляем одну запись с JSON-документов из трёх строк-объектов:
INSERT INTO json_test (data)
VALUES ('[{"value":1000}, {"value":2000}, {"value":3000}]');

# 3. Выбираем данные:
SELECT
    id,
    SUM(j.cost) # j - псевдоним таблицы-результата JSON_TABLE()
FROM test t
JOIN JSON_TABLE(
    t.data, # t - псевдоним главной таблицы
    '$[*]' COLUMNS ( # Здесь указываем путь к корню JSON-документа
        cost INT PATH '$.value' # Здесь снова указываем путь, но уже относительно "строки" данных, а не корня документа
    )
) AS j # Нет части ON; её функцию выполняет упоминание главной таблицы в первом аргументе JSON_TABLE
GROUP BY id # Результат группируем!
 

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson