MySql JSON запрос между диапазоном - PullRequest
0 голосов
/ 18 июня 2020

У меня есть таблица card_percentage с DDL:

CREATE TABLE card_percentage
(
    id   int UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    jdoc json NULL
);

В ней одна строка данных

id | jdoc
------------ 
 1 | {"AMXC": [{"enabled": "y", "bank_code": "AMXC", "max_amount": 99999999.99, "min_amount": 0.0, "percentage": 2.5}], "VISA": [{"enabled": "y", "bank_code": "VISA", "max_amount": 1999.99, "min_amount": 0.0, "percentage": 2.8}, {"enabled": "y", "bank_code": "VISA", "max_amount": 99999999.99, "min_amount": 2000.0, "percentage": 1.8}]}

Beautified JSON для удобства чтения

{
  "AMXC": [
    {
      "enabled": "y",
      "bank_code": "AMXC",
      "min_amount": 0.0,
      "max_amount": 99999999.99,
      "percentage": 2.5
    }
  ],
  "VISA": [
    {
      "enabled": "y",
      "bank_code": "VISA",
      "min_amount": 0.0,
      "max_amount": 1999.99,
      "percentage": 2.8
    },
    {
      "enabled": "y",
      "bank_code": "VISA",
      "min_amount": 2000.0,
      "max_amount": 99999999.99,
      "percentage": 1.8
    }
  ]
}

Теперь я хочу выбрать percentage для VISA, когда сумма 200 находится между min_amount и max_amount. Для этого я использую следующий запрос, но он ничего не дает в наборе результатов.

SELECT id,
       jdoc -> '$.VISA[*].percentage' percentage
FROM card_percentage
WHERE id = 1
  AND jdoc -> '$.VISA[*].min_amount' <= 200
  AND jdoc -> '$.VISA[*].max_amount' >= 200
;

1 Ответ

2 голосов
/ 18 июня 2020

Хорошо, основываясь на комментарии @ Akina об использовании JSON_TABLE, я провел дальнейшее исследование.

Ниже приведен мой запрос, который очень хорошо работает.

SELECT id, jdoc.percentage
FROM card_percentage, JSON_TABLE(
             jdoc,
             '$.VISA[*]'
             COLUMNS (
                 rowid FOR ORDINALITY,
                 enabled VARCHAR(1) PATH '$.enabled' DEFAULT '"n"' ON EMPTY DEFAULT '"n"' ON ERROR,
                 bank_code VARCHAR(4) PATH '$.bank_code' DEFAULT '"NCOD"' ON EMPTY ,
                 min_amount INT PATH '$.min_amount' DEFAULT '0' ON EMPTY ,
                 max_amount INT PATH '$.max_amount' DEFAULT '0' ON EMPTY ,
                 percentage DECIMAL(10, 2) PATH '$.percentage' DEFAULT '0' ON EMPTY DEFAULT '0' ON ERROR
                 )
         ) AS jdoc
WHERE jdoc.min_amount <= 200
  AND jdoc.max_amount >= 200
;

Чтобы заставить это работать, эта статья «JSON_TABLE - The Best of Both Worlds» действительно помогла.

...