ARRAY_DIFFERENCE
array_difference
Описание
Вычисляет разности между соседними элементами массива. Функция обходит массив слева направо, вычисляя разность между каждым элементом и предыдущим, и возвращает новый массив той же длины, что и исходный. Разность для первого элемента всегда равна 0.
Синтаксис
array_difference(ARRAY<T> arr)
Параметры
arr:тип ARRAY<T>, массив, для которого нужно вычислить разности. Поддерживаются имена столбцов и константные значения.
Поддерживаемые типы T:
- Числовые типы: TINYINT, SMALLINT, INT, BIGINT, LARGEINT, FLOAT, DOUBLE, DECIMAL
Возвращаемое значение
Тип возвращаемого значения: ARRAY<T>
Возвращаемое значение:
- Новый массив той же длины, что и входной, в котором каждая позиция содержит разность между текущим и предыдущим элементами, а разность для первого элемента равна 0
- NULL: если входной массив равен NULL
Особенности использования:
- Если массив содержит элементы других типов (например, строки), функция пытается преобразовать их в тип DOUBLE. Элементы, которые не удалось преобразовать, становятся null и не участвуют в вычислении разностей.
- Функция пытается преобразовать все элементы в совместимые числовые типы для вычисления разностей, а тип возвращаемого результата выбирается автоматически на основе входного типа:
- Для входного типа DOUBLE или FLOAT возвращается ARRAY<DOUBLE>
- Для целочисленного входного типа возвращается ARRAY<BIGINT> или ARRAY<LARGEINT>
- Для входного типа DECIMAL возвращается ARRAY<DECIMAL> с сохранением исходных точности и масштаба
- Разности вычисляются слева направо: каждая позиция содержит разность между текущим и предыдущим элементами, а первый элемент равен 0.
- Для пустого массива возвращается пустой массив, для массива NULL возвращается NULL, для массива с единственным элементом возвращается [0].
- Сложные типы (вложенные массивы, MAP, STRUCT) не поддерживают вычисление разностей; вызов функции приводит к ошибке.
- Значения null в элементах массива влияют на последующие вычисления разностей: если предыдущий элемент равен null, текущая разность будет равна null
Примеры
CREATE TABLE array_difference_test (
id INT,
int_array ARRAY<INT>,
double_array ARRAY<DOUBLE>
)
DUPLICATE KEY(id)
DISTRIBUTED BY HASH(id) BUCKETS 3
PROPERTIES (
"replication_num" = "1"
);
INSERT INTO array_difference_test VALUES
(1, [1, 3, 6, 10, 15], [1.1, 3.3, 6.6, 11.0, 16.5]),
(2, [10, 30, 60], [10.5, 41.0, 76.5]),
(3, [], []),
(4, NULL, NULL);
Примеры запросов:
Разности для int_array: каждая позиция содержит разность между текущим и предыдущим элементами, а первый элемент равен 0.
SELECT array_difference(int_array) FROM array_difference_test WHERE id = 1;
+-----------------------------+
| array_difference(int_array) |
+-----------------------------+
| [0, 2, 3, 4, 5] |
+-----------------------------+
Разности для double_array: для массива чисел с плавающей точкой результат также содержит числа с плавающей точкой.
Обратите внимание, что результат на второй позиции равен 2.1999999999999997. Это связано с небольшой погрешностью, обусловленной точностью двоичного представления чисел с плавающей точкой (3.3 - 1.1 невозможно точно представить в двоичной форме как 2.2). Последующие значения 3.3, 4.4, 5.5 могут выглядеть как «обычные значения», но на самом деле они также являются двоичными приближениями, которые после округления совпадают с десятичными значениями. Это явление встречается во всех системах, использующих числа с плавающей точкой по стандарту IEEE 754 (включая MySQL, Snowflake, Python, JavaScript и другие).
SELECT array_difference(double_array) FROM array_difference_test WHERE id = 1;
+------------------------------------------+
| array_difference(double_array) |
+------------------------------------------+
| [0, 2.1999999999999997, 3.3, 4.4, 5.5] |
+------------------------------------------+
Для пустого массива возвращается пустой массив:
SELECT array_difference(int_array) FROM array_difference_test WHERE id = 3;
+-----------------------------+
| array_difference(int_array) |
+-----------------------------+
| [] |
+-----------------------------+
Для массива NULL возвращается NULL: если входной массив равен NULL, функция возвращает NULL без ошибки.
SELECT array_difference(int_array) FROM array_difference_test WHERE id = 4;
+-----------------------------+
| array_difference(int_array) |
+-----------------------------+
| NULL |
+-----------------------------+
Для массива с единственным элементом возвращается [0]:
SELECT array_difference([42]);
+------------------------+
| array_difference([42]) |
+------------------------+
| [0] |
+------------------------+
Массив, содержащий значения null: если предыдущий элемент равен null, текущая разность будет равна null.
SELECT array_difference([1, null, 3, null, 5]);
+-----------------------------------------+
| array_difference([1, null, 3, null, 5]) |
+-----------------------------------------+
| [0, null, null, null, null] |
+-----------------------------------------+
Если массив содержит строки и числа, элементы, которые можно преобразовать в числа, участвуют в вычислении разностей. Элементы, которые преобразовать не удалось, становятся null, и результат на соответствующей позиции будет равен null.
SELECT array_difference(['a', 1, 'b', 2, 'c', 3]);
+--------------------------------------------+
| array_difference(['a', 1, 'b', 2, 'c', 3]) |
+--------------------------------------------+
| [null, null, null, null, null, null] |
+--------------------------------------------+
Примеры со сложными типами:
Тип вложенного массива не поддерживается, возникает ошибка.
SELECT array_difference([[1,2,3]]);
ERROR 1105 (HY000): errCode = 2, detailMessage = Can not find the compatibility function signature: array_difference(ARRAY<ARRAY<TINYINT>>)
Тип Map не поддерживается, возникает ошибка.
SELECT array_difference([{'k':1},{'k':2}]);
ERROR 1105 (HY000): errCode = 2, detailMessage = Can not find the compatibility function signature: array_difference(ARRAY<MAP<VARCHAR(1),TINYINT>>)
Тип Struct не поддерживается, возникает ошибка.
SELECT array_difference(array(named_struct('name','Alice','age',20),named_struct('name','Bob','age',30)));
ERROR 1105 (HY000): errCode = 2, detailMessage = Can not find the compatibility function signature: array_difference(ARRAY<STRUCT<name:TEXT,age:TINYINT>>)
Неверное количество параметров приводит к ошибке.
SELECT array_difference([1,2,3],[4,5,6]);
ERROR 1105 (HY000): errCode = 2, detailMessage = Can not found function 'array_difference' which has 2 arity. Candidate functions are: [array_difference(Expression)]
Передача значения, тип которого не является массивом, приводит к ошибке.
SELECT array_difference('not_an_array');
ERROR 1105 (HY000): errCode = 2, detailMessage = Can not find the compatibility function signature: array_difference(VARCHAR(12))
Ключевые слова
ARRAY, DIFFERENCE, ARRAY_DIFFERENCE