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 NULLis 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
pricesand 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
ARRAYof 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