#mysql #json
#mysql #json
Вопрос:
моя проблема в том, что когда я пытаюсь взять данные с помощью функции mysql JSON_EXTRACT, дело в том, что я делаю с индексом [0], и все работает нормально, но когда я запрашиваю следующий [1], возвращает null . Я пытался без индекса узнать, как искать, и это вернуло все мои данные json, и когда я попытался занять индексированную позицию поверх позиции 0, не возвращает никаких данных, только null. Вот мой пример кода:
set @example = '{"product":{
"id_product":1,
"quantity":1
},
"product":{
"id_product":3,
"quantity":4
},
"product":{
"id_product":5,
"quantity":2
}
}';
select JSON_EXTRACT(@example, '$.product[0].id_product'); -- Returns '1'
select JSON_EXTRACT(@example, '$.product[1].id_product'); -- Returns null, should be '3'
Я хотел бы знать, как именно это работает, если на самом деле это не так.
Заранее спасибо.
Ответ №1:
Выигрывает последний дубликат ключа.
11.6 Тип данных JSON :: Нормализация, объединение и автоматическое преобразование значений JSON
…
Это поведение «выигрывает последний дубликат ключа» предложено RFC 7159 и реализовано большинством анализаторов JavaScript.
…
В версиях MySQL до версии 8.0.3 элементы с ключами, которые дублировали ключ, найденный ранее в документе, были отброшены.
…
Пример:
mysql> SELECT VERSION();
-----------
| VERSION() |
-----------
| 8.0.15 |
-----------
1 row in set (0.00 sec)
mysql> SET @`example` := '{
'> "product": {
'> "id_product": 1,
'> "quantity": 1
'> },
'> "product": {
'> "id_product": 3,
'> "quantity": 4
'> },
'> "product": {
'> "id_product": 5,
'> "quantity": 2
'> }
'> }';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT JSON_VALID(@`example`);
------------------------
| JSON_VALID(@`example`) |
------------------------
| 1 |
------------------------
1 row in set (0.01 sec)
mysql> SELECT JSON_LENGTH(@`example`);
-------------------------
| JSON_LENGTH(@`example`) |
-------------------------
| 1 |
-------------------------
1 row in set (0.00 sec)
mysql> SELECT JSON_EXTRACT(@`example`, '$.product');
---------------------------------------
| JSON_EXTRACT(@`example`, '$.product') |
---------------------------------------
| {"quantity": 2, "id_product": 5} |
---------------------------------------
1 row in set (0.00 sec)
Некоторые параметры
Вариант 0:
mysql> SET @`example` := '{
'> "product_0": {
'> "id_product": 1,
'> "quantity": 1
'> },
'> "product_1": {
'> "id_product": 3,
'> "quantity": 4
'> },
'> "product_2": {
'> "id_product": 5,
'> "quantity": 2
'> }
'> }';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT JSON_VALID(@`example`);
------------------------
| JSON_VALID(@`example`) |
------------------------
| 1 |
------------------------
1 row in set (0.00 sec)
mysql> SELECT JSON_LENGTH(@`example`);
-------------------------
| JSON_LENGTH(@`example`) |
-------------------------
| 3 |
-------------------------
1 row in set (0.00 sec)
mysql> SELECT
-> JSON_EXTRACT(@`example`, '$.product_0.id_product'),
-> JSON_EXTRACT(@`example`, '$.product_1.id_product'),
-> JSON_EXTRACT(@`example`, '$.product_2.id_product')G
*************************** 1. row ***************************
JSON_EXTRACT(@`example`, '$.product_0.id_product'): 1
JSON_EXTRACT(@`example`, '$.product_1.id_product'): 3
JSON_EXTRACT(@`example`, '$.product_2.id_product'): 5
1 row in set (0.00 sec)
Вариант 1:
mysql> SET @`example` := '[
'> {
'> "product": {
'> "id_product": 1,
'> "quantity": 1
'> }
'> },
'> {
'> "product": {
'> "id_product": 3,
'> "quantity": 4
'> }
'> },
'> {
'> "product": {
'> "id_product": 5,
'> "quantity": 2
'> }
'> }]';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT JSON_VALID(@`example`);
------------------------
| JSON_VALID(@`example`) |
------------------------
| 1 |
------------------------
1 row in set (0.00 sec)
mysql> SELECT JSON_LENGTH(@`example`);
-------------------------
| JSON_LENGTH(@`example`) |
-------------------------
| 3 |
-------------------------
1 row in set (0.00 sec)
mysql> SELECT
-> JSON_EXTRACT(@`example`, '$[0].product.id_product'),
-> JSON_EXTRACT(@`example`, '$[1].product.id_product'),
-> JSON_EXTRACT(@`example`, '$[2].product.id_product')G
*************************** 1. row ***************************
JSON_EXTRACT(@`example`, '$[0].product.id_product'): 1
JSON_EXTRACT(@`example`, '$[1].product.id_product'): 3
JSON_EXTRACT(@`example`, '$[2].product.id_product'): 5
1 row in set (0.00 sec)
Комментарии:
1. Отлично, я думаю, хотя использование mysql версии 5.7 (которую я использую), поддерживающей json, не работает должным образом, и лучший способ добиться этого — использовать, как и вы, 8.0.
2. @RamonB.C.: В MySQL 5.7 оба параметра работают без проблем, см. dbfiddle .