如何在MySQL的JSON数据类型列中按关键字分组

时间:2019-12-29 17:07:08

标签: mysql json mysql-8.0

我的order_summary表中的JSON列orders具有以下结构,

//Order 1
{
  "total": 16.895,
  .....
  "products": [
    {
      ...,
      "quantity": 2,
      "variant_id": 98
    },
    {
      ...,
      "quantity": 3,
      "variant_id": 99
    },
  ],
}
//Order 2
{
  "total": 10.895,
  .....
  "products": [
    {
      ...,
      "quantity": 2,
      "variant_id": 98
    },
    {
      ...,
      "quantity": 4,
      "variant_id": 100
    },
  ],
}

现在,我需要找到每个variant_id

的总销售量

我正在关注以下内容

SELECT sum(order_summary->"$.products[*].quantity") 
FROM orders  
GROUP BY order_summary->"$.products[*].variant_id"

但是我只是得到零。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

order_summary->"$.products[*].quantity"产生一个数组。

mysql> SELECT order_summary->"$.products[*].quantity" from orders;
+-----------------------------------------+
| order_summary->"$.products[*].quantity" |
+-----------------------------------------+
| [2, 3]                                  |
| [2, 4]                                  |
+-----------------------------------------+

总和为0。

mysql> select sum("[2,3]");
+--------------+
| sum("[2,3]") |
+--------------+
|            0 |
+--------------+

要使其工作,首先必须使用json_table将JSON转换为行。然后,它们可以像普通列一样聚合。​​

select products.*
from orders,
    json_table(
      -- select the JSON column from orders
      orders.order_summary,
      -- filter only the products
      "$.products[*]"
      -- translate them into columns
      columns(
        quantity int path "$.quantity",
        variant_id int path "$.variant_id"
      )
    ) products
;

+----------+------------+
| quantity | variant_id |
+----------+------------+
|        2 |         98 |
|        3 |         99 |
|        2 |         98 |
|        4 |        100 |
+----------+------------+

然后我们可以正常操作products伪表。

select products.variant_id, sum(products.quantity)
from orders,
    json_table(
      order_summary,
      "$.products[*]"
      columns(
        quantity int path "$.quantity",
        variant_id int path "$.variant_id"
      )
    ) products
group by products.variant_id;

+------------+------------------------+
| variant_id | sum(products.quantity) |
+------------+------------------------+
|         98 |                      4 |
|         99 |                      3 |
|        100 |                      4 |
+------------+------------------------+