MySQL 实验室 JSON 本机类型:如何对 jsn_extract 返回的数组结果求和?

MySQL Labs JSON native type: How SUM the result of an array returned by jsn_extract?

下面是我的场景:

CREATE TABLE `CustomerOrder` (
  `id` bigint(11) unsigned NOT NULL AUTO_INCREMENT,
  `data` json DEFAULT NULL,
  PRIMARY KEY (`id`)
);

我们可以使用此客户订单 json 作为示例:

{ 
    "creation": "2015-07-30 14:27:51",
    "customer": {
        "id": 2,
        "email": "foo@bar.com"
    },
    "item": [
        {
            "sku": 182,
            "unitPrice": 0.89,
            "qty": 10
        }, {
            "sku": 712,
            "unitPrice": 12.99,
            "qty": 2
        }
    ]
}

在 MySQL 控制台上运行 SQL:

SELECT json_extract(data, '$.item[*].unitPrice') AS price FROM CustomerOrder;

我将得到这个输出:

[ 0.89, 12.99 ]

现在如何计算 [0.89 + 12.99] 或 1..N 个项目元素的 SUM?

对于我的测试,我使用了这个版本的 MySQL 实验室:

http://downloads.mysql.com/snapshots/pb/mysql-5.7.7-labs-json/mysql-5.7.7-labs-json-linux-el6-x86_64.tar.gz

http://mysqlserverteam.com/json-labs-release-native-json-data-type-and-binary-format/

试试这个:

SELECT (json_extract(data, '$.item[0].unitPrice') + json_extract(data, '$.item[1].unitPrice')) AS price  FROM CustomerOrder

MySQL 还不支持 table 函数(希望很快!),所以我们没有方便的 JSON 函数来从 JSON 生成行大批。现在,Victor Smt 使用存储过程的建议也是我的首选。

DagW

下面的存储函数对我有用:

delimiter $$
create function sum_array_cells( input_array json )
returns double
language sql deterministic contains sql
begin
    declare array_length integer;
    declare retval double;
    declare cell_value double;
    declare idx int;

    select json_length( input_array ) into array_length;

    set retval = 0.0;

    set idx = 0;
    while idx < array_length do
        select json_extract( input_array, concat( '$[', idx, ']' ) )
        into cell_value;

        set retval = retval + cell_value;
        set idx = idx + 1;
    end while;

    return retval;

end$$

然后您将在这样的查询中调用该函数

select sum_array_cells( '[ 0.89, 12.99, 5.23, 2.04 ]' );

希望这对您有所帮助, -瑞克

不知道为什么我的代码示例被截断了。这是函数的其余部分:



    select json_extract( input_array, concat( '$[', idx, ']' ) )
    into cell_value;

    set retval = retval + cell_value;
    set idx = idx + 1;
  end while;

  return retval;

end$$

我尝试使用@Rick 的回答,但它对我不起作用。所以我为 mysql 函数挖掘了 mysql 文档。这是 mysql 5.7.14,

的工作函数
create function sum_array_cells( input_array json )
returns double
BEGIN
    DECLARE array_length INTEGER(11);
    DECLARE retval DOUBLE(19,2);
    DECLARE cell_value DOUBLE(19,2);
    DECLARE idx INT(11);

    SELECT json_length( input_array ) INTO array_length;

    SET retval = 0.0;

    SET idx = 0;

    WHILE idx < array_length DO
        SELECT json_extract( input_array, concat( '$[', idx, ']' ) )
            INTO cell_value;

        SET retval = retval + cell_value;
        SET idx = idx + 1;
    END WHILE;

    RETURN retval;
END

然后使用@Rick 写的函数:

select sum_array_cells( '[ 0.89, 12.99, 5.23, 2.04 ]' );

使用JSON_TABLE见例子:

SET @datax = '[
  { "product":"apple",  "price": 5}, 
  { "product":"banana",  "price": 7}
]';


SELECT price.* 
FROM 
     JSON_TABLE(@datax, '$[*]' COLUMNS (
                price INTEGER PATH '$.price')
     ) price;`

然后,加价。

的优化和更新版本。 在 MySQL 5.7、MySQL 8.0 和 MariaDB 10.3 上测试。

请注意,它使用小数来保证准确性。随意将其更改为 double 或 int。

CREATE FUNCTION zy_json_sum ( js_array json )
RETURNS decimal(18,2) DETERMINISTIC
BEGIN
    DECLARE total decimal(18,2) DEFAULT 0.0;
    DECLARE idx int DEFAULT 0;
    SELECT json_length( js_array ) INTO idx;
    WHILE idx > 0 DO
        SET idx = idx - 1;
        SELECT json_extract( js_array, concat( '$[', idx, ']' ) ) + total INTO total;
    END WHILE;
    RETURN total;
END

用法:

SELECT zy_json_sum( '[1.1, 2.2, "3.3 foo", null, -4.4]' )
-- Output: 2.20