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://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
下面是我的场景:
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://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;`
然后,加价。
请注意,它使用小数来保证准确性。随意将其更改为 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