Извлечение пути Mysql JSON по основному значению запроса

Таблица: информация

id     | info
------ | ------
1      | {"v1": "test", "v2": "work"}

Таблица: мои_данные

id     | name     | info_id
------ | ------   | ------
1      | john     | 2
2      | peter    | 1
3      | luc      | 2

Я хотел бы иметь следующий вывод:

name     | art
------   | ------
john     | work
peter    | test
luc      | work

Моя проблема в том, что я не знаю, как использовать значение из основного запроса в качестве пути json.

Прямо сейчас у меня есть это:

SELECT a.name, (SELECT info->>"$.v1" AS art FROM infos AS b) FROM my_data AS a

Наверняка это показывает для всех "тестов"

Запрос должен быть примерно таким:

SELECT a.name, (SELECT info->>CONCAT("$.v", a.info_id) AS art FROM infos AS b) FROM my_data AS a

Это возможно?


person BobderHund    schedule 09.08.2017    source источник
comment
Мы можем просто проверить, какую версию MySQL вы используете? Может быть, я «старой школы» (я), но у меня был бы сильный соблазн не хранить данные json.   -  person Strawberry    schedule 09.08.2017
comment
Конечно, версия 5.7.19   -  person BobderHund    schedule 09.08.2017


Ответы (1)


Вы можете попробовать следующее (при необходимости отрегулируйте):

mysql> SELECT VERSION();
+-----------+
| VERSION() |
+-----------+
| 5.7.19    |
+-----------+
1 row in set (0.00 sec)

mysql> DROP TABLE IF EXISTS `my_data`, `infos`;
Query OK, 0 rows affected, 2 warnings (0.00 sec)

mysql> CREATE TABLE IF NOT EXISTS `infos` (
    ->   `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    ->   `info` JSON NOT NULL
    -> );
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE IF NOT EXISTS `my_data` (
    ->   `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    ->   `name` VARCHAR(255) NOT NULL,
    ->   `info_id` BIGINT UNSIGNED NOT NULL
    -> );
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO `infos`
    ->   (`info`)
    -> VALUES
    ->   ('{"v1": "test", "v2": "work"}');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO `my_data`
    ->   (`name`, `info_id`)
    -> VALUES
    ->   ('john', 2),
    ->   ('peter', 1),
    ->   ('luc', 2);
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> SELECT
    ->   `md`.`name`,
    ->   JSON_UNQUOTE(
    ->     JSON_EXTRACT(
    ->       `i`.`info`,
    ->       CONCAT('$.v', `md`.`info_id`)
    ->     )
    ->   ) `art`
    -> FROM
    ->   `my_data` `md`
    ->   INNER JOIN `infos` `i` ON `i`.`id` = 1;
+-------+------+
| name  | art  |
+-------+------+
| john  | work |
| peter | test |
| luc   | work |
+-------+------+
3 rows in set (0.00 sec)

См. db-fiddle.

person wchiquito    schedule 09.08.2017
comment
Вау, вот оно. Довольно простой способ. Хороший. - person BobderHund; 09.08.2017