REDUCE
On this page
REDUCE()
is a scalar function that applies an expression to each element of an array and returns a single value as the result.
This function takes an initial value, an array, and a scalar expression (accumulator expression) as inputs.REDUCE_
and REDUCE_
functions which serve as the placeholder for the accumulator and the current value, respectively.
Note: This function does not directly accept or return JSON data.JSON_
.
Syntax
REDUCE(<initial_value>, <array_input>, <accumulator_expression>)
Arguments
-
initial_
: Any literal, variable, or expression that evaluates to a scalar data type.value -
array_
: An array of scalar values or any expression that resolves to an array of scalar values.input -
accumulator_
: Any literal, variable, or expression that evaluates to a scalar data type.expression This argument supports following placeholder functions: -
REDUCE_
: Placeholder function for the accumulator.ACC() -
REDUCE_
: Placeholder function that returns the index of the current iteration in the array.INDEX() The array uses a 0-based index. -
REDUCE_
: Placeholder function that returns the current value.VALUE()
-
Remarks
-
The data type of
initial_
determines the data type of each iteration, and consequently, the data type of the result.value If NULL
is passed as theinitial_
, the array type determines the data type of the result.value You can also explicitly typecast the data type of initial_
to another type to modify the data type of the result.value -
If the specified array is empty, the
initial_
is returned as the result.value -
Aggregate functions, non-scalar functions, and sub-selects are not supported inside the accumulator expression.
Examples
Here are some examples:
-
Add all the elements in an array:
SELECT REDUCE(0,JSON_TO_ARRAY('[1,2,3,4]'),REDUCE_ACC() + REDUCE_VALUE()) AS Result;+--------+ | Result | +--------+ | 10 | +--------+
-
Apply a mapping to an array, which multiplies each element in the array by 10:
SELECT REDUCE('[]':>JSON,JSON_TO_ARRAY('[1,2,3,4]'),JSON_ARRAY_PUSH_JSON(REDUCE_ACC(),REDUCE_VALUE()*10)) AS Result;+---------------+ | Result | +---------------+ | [10,20,30,40] | +---------------+
-
Implement a filter and return odd numbers in an array:
SELECT REDUCE('[]':>JSON,JSON_TO_ARRAY('[1,2,3,4]'),IF(REDUCE_VALUE()%2!=0,JSON_ARRAY_PUSH_JSON(REDUCE_ACC(),REDUCE_VALUE()),REDUCE_ACC())) AS Result;+--------+ | Result | +--------+ | [1,3] | +--------+
-
Return the index of the first occurrence of the number 3 in an array:
SELECT REDUCE(-1,JSON_TO_ARRAY('[1,2,3,4,3]'),IF(REDUCE_ACC() < 0 && REDUCE_VALUE()<=>'3',REDUCE_INDEX(),REDUCE_ACC())) AS Result;+--------+ | Result | +--------+ | 2 | +--------+
If the array doesn't contain the search value, the initial value is returned instead.
SELECT REDUCE(-1,JSON_TO_ARRAY('[1,2,4]'),IF(REDUCE_ACC() < 0 && REDUCE_VALUE()<=>'3',REDUCE_INDEX(),REDUCE_ACC())) AS Result;+--------+ | Result | +--------+ | -1 | +--------+
-
Return the index of all the occurrences in the array:
SELECT REDUCE('[]':>JSON,JSON_TO_ARRAY('[1,2,3,4,3]'),IF(NOT REDUCE_VALUE() IN (3),REDUCE_ACC(),JSON_ARRAY_PUSH_JSON(REDUCE_ACC(),REDUCE_INDEX()))) As Result;+--------+ | Result | +--------+ | [2,4] | +--------+
-
Concatenate multiple arrays:
SET @INPUT = '[["a","b"],["c","d","e"],["f","g"]]';SELECT REDUCE('[]':>JSON,JSON_TO_ARRAY(@INPUT),REDUCE(REDUCE_ACC(),JSON_TO_ARRAY(REDUCE_VALUE()),JSON_ARRAY_PUSH_JSON(REDUCE_ACC(),REDUCE_VALUE()))) As Result;+-------------------------------+ | Result | +-------------------------------+ | ["a","b","c","d","e","f","g"] | +-------------------------------+
-
Concatenate all the elements in an array:
SELECT REDUCE("",["A","B","C"]:>ARRAY(TEXT NOT NULL),CONCAT(REDUCE_ACC(), REDUCE_VALUE()) ) AS Result;+--------+ | Result | +--------+ | ABC | +--------+
-
The following example aggregates the
prices
and returns the total price for eachproduct_
.id CREATE TABLE orders (order_id INT,product_id INT,quantity INT,prices JSON);INSERT INTO orders (order_id, product_id, quantity, prices) VALUES(1, 101, 5, '[10, 20, 30, 40, 50]'),(2, 102, 3, '[15, 25, 35]'),(3, 101, 2, '[10, 20]'),(4, 103, 4, '[30, 40, 50, 60]'),(5, 102, 6, '[15, 25, 35, 45, 55, 65]'),(6, 101, 3, '[10, 20, 30]'),(7, 104, 7, '[20, 30, 40, 50, 60, 70, 80]'),(8, 103, 2, '[30, 40]'),(9, 102, 4, '[15, 25, 35, 45]'),(10, 101, 1, '[10]');SELECT product_id, SUM(REDUCE(0,JSON_TO_ARRAY(prices),REDUCE_ACC() + REDUCE_VALUE())) AS "Total Price"FROM orders GROUP BY product_id;+------------+-------------+ | product_id | Total Price | +------------+-------------+ | 101 | 250 | | 102 | 435 | | 103 | 250 | | 104 | 350 | +------------+-------------+
-
Convert an
ARRAY
of arbitrary type to a JSON array:SELECT REDUCE('[]':>JSON,['apple', 'banana', 'cherry', 'date', 'elderberry', 'fig']:>ARRAY(LONGTEXT),JSON_ARRAY_PUSH_JSON(REDUCE_ACC(), TO_JSON(REDUCE_VALUE()))) AS Result;+-------------------------------------------------------+ | Result | +-------------------------------------------------------+ | ["apple","banana","cherry","date","elderberry","fig"] | +-------------------------------------------------------+
Last modified: September 26, 2024