【问题标题】:MySql JSON query between a range范围之间的MySql JSON查询
【发布时间】:2020-06-18 08:30:41
【问题描述】:

我有一张桌子 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}]}

美化 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
    }
  ]
}

现在,当 200 的金额介于 min_amountmax_amount 之间时,我想为 VISA 选择 percentage。为此,我使用以下查询,但结果集中没有给出任何内容。

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

【问题讨论】:

  • dbfiddle.uk/… - 它显示您的问题来源。您必须将 JSON 转换为表格(使用 JSON_TABLE() function)。
  • 请向我们展示您想要的样本数据结果。
  • @GMB 当然他想得到一个值为(1, 2.8)...
  • @Akina,根据您的输入,我尝试了 JSON_TABLE,它真的很有趣。让我发布一个包含更多详细信息的答案。
  • 为什么要“让”?这是最好的选择...

标签: mysql sql json mysql-8.0


【解决方案1】:

好的,基于@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" 真的很有帮助。

【讨论】:

  • 解析未使用的列有什么好处? rowid、已启用、bank_code...
  • 当然只有 min_amount、max_amount 和百分比就足够了,我在生产代码中只使用这三列。我想强调'"n"' 是如何默认设置的,这很重要,因为'n' 不起作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-06
  • 2014-06-13
  • 2021-11-15
  • 2014-02-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多