Перейти к содержимому
Последнее обновление

ARRAY_DIFFERENCE

array_difference​

SinceVersion 2.0.0

Описание​

Вычисляет разности между соседними элементами массива. Функция обходит массив слева направо, вычисляя разность между каждым элементом и предыдущим, и возвращает новый массив той же длины, что и исходный. Разность для первого элемента всегда равна 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