运算符和函数 - Amazon Redshift

从补丁 198 开始,Amazon Redshift 将不再支持创建新的 Python UDF。现有的 Python UDF 将继续正常运行至 2026 年 6 月 30 日。有关更多信息,请参阅博客文章

运算符和函数

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

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

算术运算符

SUPER 值支持使用动态类型的所有基本算术运算符 +、-、*、/、%。运算的结果类型保持为 SUPER。对于所有运算符(二进制运算符 + 除外),输入操作数必须是数字。否则,Amazon Redshift 返回 null。当 Amazon Redshift 运行这些运算符且动态类型不改变时,小数和浮点值之间的区别将保留。但是,使用乘法和除法时,小数位数会发生变化。算术溢出仍然会导致查询错误,它们不会更改为 null。如果输入是数字,则二进制运算符 + 执行加法;如果输入是字符串,则执行串联。如果一个操作数是字符串,另一个操作数是数字,则结果为 null。如果 SUPER 值不是以下示例所示的数字,则一元前缀运算符 + 和-返回 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 会将另一个操作数升级为浮点数,并以浮点数的形式生成结果。

算术函数

Amazon Redshift 支持 SUPER 列的以下算术函数。如果输入不是数字,则它们返回 null:

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

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 消除了输入小数的小数位数。

数组函数

Amazon Redshift 支持以下数组组合和实用程序函数:

您可以使用 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_CONCAT 函数结合使用:

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_FLATTEN 将多个级别的数组合并到单个数组中:

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_CONCAT 和 ARRAY_FLATTEN 使用动态键入规则。如果输入不是数组,则它们返回 null 而不是错误。GET_ARRAY_LENGTH 函数在给定对象或数组路径的情况下返回 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_TO_ARRAY 将字符串拆分为字符串数组。函数将分隔符用作可选参数。如果没有分隔符,则默认值为逗号。

SELECT SPLIT_TO_ARRAY('12|345|6789', '|'); split_to_array --------------------- ["12","345","6789"] (1 row)

排序规则行为

借助 SUPER,您可以通过 CREATE TABLE 设置列的排序规则,通过 CREATE DATABASE 采用默认排序规则集,并通过 COLLATE 函数设置表达式的排序规则。

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

信息函数

SUPER 数据列支持返回有关 SUPER 值的动态类型和其他类型信息的检查函数。最常见的示例是返回具有布尔值、数字、字符串、对象、数组或 null 的 VARCHAR 的 JSON_TYPEOF 标量函数,具体取决于 SUPER 值的动态类型。Amazon Redshift 支持以下针对 SUPER 数据列的布尔函数:

有关 SUPER 类型信息函数的更多信息,请参阅 SUPER 类型信息函数

字符串函数

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

字符串函数现在支持最多 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