从 2025 年 11 月 1 日起,Amazon Redshift 将不再支持创建新的 Python UDF。如果您想要使用 Python UDF,请在该日期之前创建 UDF。现有的 Python UDF 将继续正常运行。有关更多信息,请参阅博客文章
运算符和函数
借助 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:
FLOOR。有关更多信息,请参阅 FLOOR 函数。
CEIL 和 CEILING。有关更多信息,请参阅 CEILING(或 CEIL)函数。
ROUND。有关更多信息,请参阅 ROUND 函数。
TRUNC。有关更多信息,请参阅 TRUNC 函数。
ABS。有关更多信息,请参阅 ABS 函数。
以下示例使用算术函数查询数据:
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。有关更多信息,请参阅 数组函数。
ARRAY_CONCAT。有关更多信息,请参阅 array_concat 函数。
ARRAY_FLATTEN。有关更多信息,请参阅 array_flatten 函数。
GET_ARRAY_LENGTH。有关更多信息,请参阅 get_array_length 函数。
SPLIT_TO_ARRAY。有关更多信息,请参阅 split_to_array 函数。
SUBARRAY。有关更多信息,请参阅 子数组函数。
您可以使用 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