

 从补丁 198 开始，Amazon Redshift 将不再支持创建新的 Python UDF。现有的 Python UDF 将继续正常运行至 2026 年 6 月 30 日。有关更多信息，请参阅[博客文章](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/)。

# 运算符和函数
<a name="operators-functions"></a>

借助 Amazon Redshift，您可以使用包含运算符和函数的 SUPER 数据对大型数据集执行高级分析。用于 SUPER 数据的运算符和函数是一种 SQL 结构，可对存储在 Amazon Redshift 表中的半结构化数据进行复杂的分析和操作。

以下各节将介绍在 Amazon Redshift 中使用运算符和函数处理 SUPER 数据的语法、示例和最佳实践，以充分挖掘半结构化数据的潜力。

## 算术运算符
<a name="arithmetic-opertors"></a>

SUPER 值支持使用动态类型的所有基本算术运算符 \$1、-、\$1、/、%。运算的结果类型保持为 SUPER。对于所有运算符（二进制运算符 \$1 除外），输入操作数必须是数字。否则，Amazon Redshift 返回 null。当 Amazon Redshift 运行这些运算符且动态类型不改变时，小数和浮点值之间的区别将保留。但是，使用乘法和除法时，小数位数会发生变化。算术溢出仍然会导致查询错误，它们不会更改为 null。如果输入是数字，则二进制运算符 \$1 执行加法；如果输入是字符串，则执行串联。如果一个操作数是字符串，另一个操作数是数字，则结果为 null。如果 SUPER 值不是以下示例所示的数字，则一元前缀运算符 \$1 和-返回 null：

```
SELECT (c_orders[0]. o_orderkey + 0.5) * c_orders[0]. o_orderkey / 10 AS math FROM customer_orders_lineitem;
            math
----------------------------
 1757958232200.1500
(1 row)
```

动态键入允许 SUPER 中的十进制值具有不同的小数位数。Amazon Redshift 将十进制值视为不同的静态类型，并允许所有数学运算。Amazon Redshift 根据操作数的小数位数动态计算产生的小数位数。如果其中一个操作数是浮点数，则 Amazon Redshift 会将另一个操作数升级为浮点数，并以浮点数的形式生成结果。

## 算术函数
<a name="arithmetic-functions"></a>

Amazon Redshift 支持 SUPER 列的以下算术函数。如果输入不是数字，则它们返回 null：
+ FLOOR。有关更多信息，请参阅 [FLOOR 函数](r_FLOOR.md)。
+ CEIL 和 CEILING。有关更多信息，请参阅 [CEILING（或 CEIL）函数](r_CEILING_FLOOR.md)。
+ ROUND。有关更多信息，请参阅 [ROUND 函数](r_ROUND.md)。
+ TRUNC。有关更多信息，请参阅 [TRUNC 函数](r_TRUNC.md)。
+ ABS。有关更多信息，请参阅 [ABS 函数](r_ABS.md)。

以下示例使用算术函数查询数据：

```
SELECT x, FLOOR(x), CEIL(x), ROUND(x)
FROM (
    SELECT (c_orders[0]. o_orderkey + 0.5) * c_orders[0].o_orderkey / 10 AS x
    FROM customer_orders_lineitem
    );

         x          |     floor     |     ceil      |     round
--------------------+---------------+---------------+---------------
 1389636795898.0500  | 1389636795898  | 1389636795899  | 1389636795898
```

ABS 函数在 FLOOR、CEIL 时保留输入小数的小数位数。ROUND 消除了输入小数的小数位数。

## 数组函数
<a name="array-functions"></a>

Amazon Redshift 支持以下数组组合和实用程序函数：
+ ARRAY。有关更多信息，请参阅 [ARRAY 函数](r_array.md)。
+ ARRAY\$1CONCAT。有关更多信息，请参阅 [ARRAY\$1CONCAT 函数](r_array_concat.md)。
+ ARRAY\$1CONTAINS。有关更多信息，请参阅 [ARRAY\$1CONTAINS 函数](array_contains.md)。
+ ARRAY\$1DISTINCT。有关更多信息，请参阅 [ARRAY\$1DISTINCT 函数](array_distinct.md)。
+ ARRAY\$1EXCEPT。有关更多信息，请参阅 [ARRAY\$1EXCEPT 函数](array_except.md)。
+ ARRAY\$1FLATTEN。有关更多信息，请参阅 [ARRAY\$1FLATTEN 函数](array_flatten.md)。
+ ARRAY\$1INTERSECTION。有关更多信息，请参阅 [ARRAY\$1INTERSECTION 函数](array_intersection.md)。
+ ARRAY\$1POSITION。有关更多信息，请参阅 [ARRAY\$1POSITION 函数](array_position.md)。
+ ARRAY\$1POSITIONS。有关更多信息，请参阅 [ARRAY\$1POSITIONS 函数](array_positions.md)。
+ ARRAY\$1SORT。有关更多信息，请参阅 [ARRAY\$1SORT 函数](array_sort.md)。
+ ARRAY\$1UNION。有关更多信息，请参阅 [ARRAY\$1UNION 函数](array_union.md)。
+ ARRAYS\$1OVERLAP。有关更多信息，请参阅 [ARRAYS\$1OVERLAP 函数](arrays_overlap.md)。
+ GET\$1ARRAY\$1LENGTH。有关更多信息，请参阅 [GET\$1ARRAY\$1LENGTH 函数](get_array_length.md)。
+ SPLIT\$1TO\$1ARRAY。有关更多信息，请参阅 [SPLIT\$1TO\$1ARRAY 函数](split_to_array.md)。
+ SUBARRAY。有关更多信息，请参阅 [SUBARRAY 函数](r_subarray.md)。

您可以使用 ARRAY 函数（包括其他 SUPER 值）通过 Amazon Redshift 数据类型中的值构建 SUPER 数组。以下示例使用可变数函数 ARRAY：

```
SELECT ARRAY(1, c.c_custkey, NULL, c.c_name, 'abc') FROM customer_orders_lineitem c; 
                               array
 -------------------------------------------------------
[1,8401,null,""Customer#000008401"",""abc""]
[1,9452,null,""Customer#000009452"",""abc""]
[1,9451,null,""Customer#000009451"",""abc""]
[1,8251,null,""Customer#000008251"",""abc""]
[1,5851,null,""Customer#000005851"",""abc""] 
(5 rows)
```

以下示例将数组串联与 ARRAY\$1CONCAT 函数结合使用：

```
SELECT ARRAY_CONCAT(JSON_PARSE('[10001,10002]'),JSON_PARSE('[10003,10004]'));

             array_concat
------------------------------------
 [10001,10002,10003,10004]
(1 row)
```

以下示例将数组操作与 SUBARRAY 函数一起使用，该函数返回输入数组的子集。

```
SELECT SUBARRAY(ARRAY('a', 'b', 'c', 'd', 'e', 'f'), 2, 3);

   subarray
---------------
 ["c","d","e"]
(1 row))
```

以下示例使用 ARRAY\$1FLATTEN 将多个级别的数组合并到单个数组中：

```
SELECT x, ARRAY_FLATTEN(x) FROM (SELECT ARRAY(1, ARRAY(2, ARRAY(3, ARRAY()))) AS x);

     x           | array_flatten
 ----------------+---------------
 [1,[2,[3,[]]]]  | [1,2,3]
(1 row)
```

数组函数 ARRAY\$1CONCAT 和 ARRAY\$1FLATTEN 使用动态键入规则。如果输入不是数组，则它们返回 null 而不是错误。GET\$1ARRAY\$1LENGTH 函数在给定对象或数组路径的情况下返回 SUPER 数组的长度。

```
SELECT c_name
FROM customer_orders_lineitem
WHERE GET_ARRAY_LENGTH(c_orders) = (
    SELECT MAX(GET_ARRAY_LENGTH(c_orders))
    FROM customer_orders_lineitem
    );
```

以下示例使用 SPLIT\$1TO\$1ARRAY 将字符串拆分为字符串数组。函数将分隔符用作可选参数。如果没有分隔符，则默认值为逗号。

```
SELECT SPLIT_TO_ARRAY('12|345|6789', '|');

   split_to_array
---------------------
 ["12","345","6789"]
(1 row)
```

## 排序规则行为
<a name="collation-behavior"></a>

借助 SUPER，您可以通过 [CREATE TABLE](https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_TABLE_NEW.html) 设置列的排序规则，通过 [CREATE DATABASE](https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_DATABASE.html) 采用默认排序规则集，并通过 [COLLATE 函数](https://docs.aws.amazon.com/redshift/latest/dg/r_COLLATE.html)设置表达式的排序规则。

排序规则设置适用于存储在 SUPER 中的所有比较运算符和字符串值，无论它们是字符串值、SUPER 数组中的字符串还是 SUPER 对象的值。对于 SUPER 对象，排序规则行为仅适用于值，而不适用于属性。例如，当采用不区分大小写的排序规则时，比较 `{"attribute": "a"} = {"attribute": "A"}` 的值将返回 true，而比较 `{"attribute": "a"} = {"ATTRIBUTE": "a"}` 的值将返回 false。

## 信息函数
<a name="info-functions"></a>

SUPER 数据列支持返回有关 SUPER 值的动态类型和其他类型信息的检查函数。最常见的示例是返回具有布尔值、数字、字符串、对象、数组或 null 的 VARCHAR 的 JSON\$1TYPEOF 标量函数，具体取决于 SUPER 值的动态类型。Amazon Redshift 支持以下针对 SUPER 数据列的布尔函数：
+ [IS\$1ARRAY 函数](r_is_array.md)
+ [IS\$1BIGINT 函数](r_is_bigint.md)
+ [IS\$1CHAR 函数](r_is_char.md)
+ [IS\$1DECIMAL 函数](r_is_decimal.md)
+ [IS\$1FLOAT 函数](r_is_float.md)
+ [IS\$1INTEGER 函数](r_is_integer.md)
+ [IS\$1OBJECT 函数](r_is_object.md)
+ [IS\$1SCALAR 函数](r_is_scalar.md)
+ [IS\$1SMALLINT 函数](r_is_smallint.md)
+ [IS\$1VARCHAR 函数](r_is_varchar.md)

有关 SUPER 类型信息函数的更多信息，请参阅 [SUPER 类型信息函数](c_Type_Info_Functions.md)。

## 对象函数
<a name="object-functions"></a>

以下是 SQL 对象函数，Amazon Redshift 支持这些函数以创建 SUPER 类型对象并对这些对象执行操作：
+ [GET\$1NUMBER\$1ATTRIBUTES 函数](get_number_attributes.md)
+ [LOWER\$1ATTRIBUTE\$1NAMES 函数](r_lower_attribute_names.md)
+ [OBJECT 函数](r_object_function.md)
+ [OBJECT\$1TRANSFORM 函数](r_object_transform_function.md)
+ [UPPER\$1ATTRIBUTE\$1NAMES 函数](r_upper_attribute_names.md)

有关对象函数的更多信息，请参阅[对象函数](Object_Functions.md)。

## 字符串函数
<a name="super-examples-string-functions"></a>

要结合使用字符串函数与 SUPER 数据类型的字符串文本，必须先将字符串文本转换为字符串类型，然后再应用字符串函数。如果输入不是字符串文本，函数将返回 null。

[字符串函数](String_functions_header.md)现在支持最多 1600 万个字节。

以下示例使用 SUBSTRING 提取存储在 SUPER JSON 对象中的大小为 500 万个字节的字符串预览内容

```
CREATE TABLE customer_data (
   customer_id INT,
   profile SUPER
);

INSERT INTO customer_data VALUES (
   1,
   JSON_PARSE('{"name": "John Doe", "description": "' || REPEAT('A', 5000000) || '"}')
);

SELECT 
   customer_id,
   profile.name::VARCHAR AS name,
   SUBSTRING(profile.description::VARCHAR, 1, 50) AS description_preview
FROM customer_data;

 customer_id | name     | description_preview
-------------+----------+----------------------------------------------------
         1 | John Doe | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
```

以下示例演示如何对 SUPER 数组中的字符串文本使用 LEFT、RIGHT 和 CONCAT 函数：

```
CREATE TABLE documents (
   doc_id INT,
   chapters SUPER
);

INSERT INTO documents VALUES (
   1,
   JSON_PARSE('["' || REPEAT('hello', 400000) || '", "' || REPEAT('world', 600000) || '"]')
);

SELECT 
   doc_id,
   LEFT(chapters[0]::VARCHAR, 20) AS chapter1_start,
   RIGHT(chapters[1]::VARCHAR, 20) AS chapter2_end,
   LEN(CONCAT(chapters[0]::VARCHAR, chapters[1]::VARCHAR)) AS concat_size
FROM documents;

 doc_id |    chapter1_start    |     chapter2_end     | concat_size 
--------+----------------------+----------------------+-------------
      1 | hellohellohellohello | worldworldworldworld |     5000000
```

以下示例在 SUPER 中存储独立字符串：

```
CREATE TABLE text_storage (
   text_id INT,
   content SUPER
);

INSERT INTO text_storage VALUES 
   (1, REPEAT('A', 8000000)),
   (2, REPEAT('B', 16000000));

SELECT 
   text_id,
   LEN(content::VARCHAR) AS content_length
FROM text_storage;

 text_id | content_length
---------+----------------
      1 |        8000000
      2 |       16000000
```