此部分中的函数适用于集合类型(数组和集合)。
某些函数将聚合操作(例如 sum)应用于集合。这些函数名称都以 APPLY 开头。
此部分中的其他函数专门对数组或集合进行操作,如各个参考页所示。数组函数对原生数组值和外部表中的数组值进行操作。
注意
-
数组是从 0 开始索引的。第一个元素在 0 中的序号位置,第二个是 1,依此类推。索引对集合没有意义。
-
除非另有说明,否则函数仅适用于一维 (1D) 集合。要使用多维数组,您必须首先取消对一维数组类型的引用。集合只能是一维的。
此部分中的函数适用于集合类型(数组和集合)。
某些函数将聚合操作(例如 sum)应用于集合。这些函数名称都以 APPLY 开头。
此部分中的其他函数专门对数组或集合进行操作,如各个参考页所示。数组函数对原生数组值和外部表中的数组值进行操作。
数组是从 0 开始索引的。第一个元素在 0 中的序号位置,第二个是 1,依此类推。索引对集合没有意义。
除非另有说明,否则函数仅适用于一维 (1D) 集合。要使用多维数组,您必须首先取消对一维数组类型的引用。集合只能是一维的。
返回具有数值的 集合(数组或集合) 中所有元素的平均值。
APPLY_AVG(collection)
以下情况返回 NULL:
如果输入集合为 NULL
如果输入集合仅包含 null 值
如果输入集合为空
如果输入集合包含空元素和非空元素组合,则在计算平均值时仅考虑非空值。
=> SELECT apply_avg(ARRAY[1,2.4,5,6]);
apply_avg
-----------
3.6
(1 row)
返回 集合(数组或集合) 中非空元素的总数。要计算包括空值在内的所有元素,请使用 APPLY_COUNT_ELEMENTS (ARRAY_LENGTH)。
APPLY_COUNT(collection)
ARRAY_COUNT 是 APPLY_COUNT 的同义词。
空值不包括在计数中。
此示例中的数组包含 6 个元素,其中一个为空值:
=> SELECT apply_count(ARRAY[1,NULL,3,7,8,5]);
apply_count
-------------
5
(1 row)
返回 集合(数组或集合) 中的元素总数,包括 NULL。要仅计算非空值,请使用 APPLY_COUNT (ARRAY_COUNT)。
APPLY_COUNT_ELEMENTS(collection)
ARRAY_LENGTH 是 APPLY_COUNT_ELEMENTS 的同义词。
此函数计算所有成员,包括空值。
空集合(ARRAY[]
或 SET[]
)的长度为 0。包含单个空值(ARRAY[null]
或 SET[null]
)的集合的长度为 1。
以下数组有 6 个元素,包括一个空值:
=> SELECT apply_count_elements(ARRAY[1,NULL,3,7,8,5]);
apply_count_elements
---------------------
6
(1 row)
如上例所示,空元素是一个元素。因此,一个只包含一个空元素的数组只有一个元素:
=> SELECT apply_count_elements(ARRAY[null]);
apply_count_elements
---------------------
1
(1 row)
集合不包含重复项。如果您构造一个集合并将其直接传递给此函数,则结果可能与输入的数量不同:
=> SELECT apply_count_elements(SET[1,1,3]);
apply_count_elements
---------------------
2
(1 row)
返回 集合(数组或集合) 中最大的非空元素。该函数类似于 MAX [聚合] 函数;APPLY_MAX 对集合的元素进行操作,MAX 对诸如列选择之类的表达式进行操作。
APPLY_MAX(collection)
此函数忽略空元素。如果所有元素都为空值或集合为空白,则此函数返回空值。
=> SELECT apply_max(ARRAY[1,3.4,15]);
apply_max
-----------
15.0
(1 row)
返回 集合(数组或集合) 中最小的非空元素。该函数类似于 MIN [聚合] 函数;APPLY_MIN 对集合的元素进行操作,而 MIN 对诸如列选择之类的表达式进行操作。
APPLY_MIN(collection)
此函数忽略空元素。如果所有元素都为空值或集合为空白,则此函数返回空值。
=> SELECT apply_min(ARRAY[1,3.4,15]);
apply_min
-----------
1.0
(1 row)
计算数值(INTEGER、FLOAT、NUMERIC 或 INTERVAL)的 集合(数组或集合) 中所有元素的总和。
APPLY_SUM(collection)
以下情况返回 NULL:
如果输入集合为 NULL
如果输入集合仅包含 null 值
如果输入集合为空
=> SELECT apply_sum(ARRAY[12.5,3,4,1]);
apply_sum
-----------
20.5
(1 row)
连接元素类型和维度相同的两个数组。例如,ROW 元素必须具有相同的字段。
如果输入都是有界限的,则结果的界限是输入的界限之和。
如果任何输入均无界限,则结果是无界限的,其二进制大小是输入大小的总和。
ARRAY_CAT(array1,array2)
如果任一输入为 NULL,则函数返回 NULL。
如有必要,类型会被强制转换,如第二个示例所示。
=> SELECT array_cat(ARRAY[1,2], ARRAY[3,4,5]);
array_cat
-----------------------
[1,2,3,4,5]
(1 row)
=> SELECT array_cat(ARRAY[1,2], ARRAY[3,4,5.0]);
array_cat
-----------------------
["1.0","2.0","3.0","4.0","5.0"]
(1 row)
返回输入数组的维度。
ARRAY_DIMS(array)
=> SELECT array_dims(ARRAY[[1,2],[2,3]]);
array_dims
------------
2
(1 row)
返回数组中指定元素的序号位置,如果未找到,则返回 -1。数组可以为空白,但不能为 NULL。此函数在测试元素时使用空安全等同性检查。
ARRAY_FIND(array, val_to_find)
=> SELECT array_find(array[1,2,3],2);
array_find
------------
1
(1 row)
该函数返回指定元素的第一个实例。但是,没有什么可以确保值在数组中是唯一的。
=> SELECT array_find(ARRAY[1,2,7,5,7],7);
array_find
------------
2
(1 row)
如果未找到指定的元素,该函数将返回 -1。
=> SELECT array_find(ARRAY[1,3,5,7],4);
array_find
------------
-1
(1 row)
您可以搜索复杂的元素类型:
=> SELECT ARRAY_FIND(ARRAY[ARRAY[1,2,3],ARRAY[1,null,4]], ARRAY[1,2,3]);
ARRAY_FIND
------------
0
(1 row)
=> SELECT ARRAY_FIND(ARRAY[ARRAY[1,2,3],ARRAY[1,null,4]], ARRAY[1,null,4]);
ARRAY_FIND
------------
1
(1 row)
第二个示例,比较数组与空元素,找到匹配项,因为 ARRAY_FIND 在评估元素时使用空安全等同性检查。
如前面的示例所示,第一个实参可以是原始类型的字面量多维数组。字面量数组不能包含 ROW 元素,如直接构造语法(字面量)中所述,但表中的数组可以。有关相关示例,请参阅 CONTAINS。
如果在集合中找到指定的元素,则返回 true,否则返回 false。集合可以为空白,但不能为 NULL。此函数在测试元素时使用空安全等同性检查。
CONTAINS(collection, val_to_test)
=> SELECT CONTAINS(SET[1,2,3,4],2);
contains
----------
t
(1 row)
您可以搜索 NULL 作为元素值:
=> SELECT CONTAINS(ARRAY[1,null,2],null);
contains
----------
t
(1 row)
您可以搜索复杂的元素类型:
=> SELECT CONTAINS(ARRAY[ARRAY[1,2,3],ARRAY[1,null,4]], ARRAY[1,2,3]);
CONTAINS
----------
t
(1 row)
=> SELECT CONTAINS(ARRAY[ARRAY[1,2,3],ARRAY[1,null,4]], ARRAY[1,null,4]);
CONTAINS
----------
t
(1 row)
第二个示例,比较数组与空元素,返回 true,因为 CONTAINS 在评估元素时使用空安全等同性检查。
如前面的示例所示,第一个实参可以是原始类型的字面量多维数组。字面量数组不能包含 ROW 元素,如直接构造语法(字面量)中所述,但表中的数组可以。在以下示例中,orders 表具有以下定义:
=> CREATE EXTERNAL TABLE orders(
orderid int,
accountid int,
shipments Array[
ROW(
shipid int,
address ROW(
street varchar,
city varchar,
zip int
),
shipdate date
)
]
) AS COPY FROM '...' PARQUET;
以下查询测试特定订单。将 ROW 字面量作为第二个实参传递时,转换任何不明确的字段以确保类型匹配:
=> SELECT CONTAINS(shipments,
ROW(1,ROW('911 San Marcos St'::VARCHAR,
'Austin'::VARCHAR, 73344),
'2020-11-05'::DATE))
FROM orders;
CONTAINS
----------
t
f
f
(3 rows)
使用查询中指定的任何其他列,将集合中的一列或多列(ARRAY 或 SET)扩展为单独的表行,每个元素一行。对于每个分解的集合,结果包括两列,一列用于元素索引,另一列用于该位置的值。如果函数分解单个集合,这些列默认命名为 position
和 value
。如果函数分解两个或多个集合,则每个集合的列被命名为
pos_column-name
和
val_column-name
。您可以在 SELECT 中使用 AS 子句来更改这些列名。
此函数需要 OVER()
子句。
EXPLODE (column[,...] [USING PARAMETERS param=value])
OVER ( [window-partition-clause] )
explode_count
参数的值一样多的集合列。不是集合的列将不加修改地传递。explode_count
explode_count
的值大于指定的集合列数,则函数返回错误。此函数将集合中的每个元素展开为一行,包括空值。如果要分解的列是 NULL(非空白),则该函数不会为该集合生成任何行。
以下示例说明了将 EXPLODE()
与 OVER(PARTITION BEST)
子句一起使用。
考虑一个订单表,其中包含订单键、客户键、产品键、订单价格和电子邮件地址的列,其中一些包含数组。Vertica 中的基本查询结果如下:
=> SELECT orderkey, custkey, prodkey, orderprices, email_addrs FROM orders LIMIT 5;
orderkey | custkey | prodkey | orderprices | email_addrs
------------+---------+-----------------------------------------------+-----------------------------------+----------------------------------------------------------------------------------------------------------------
113-341987 | 342799 | ["MG-7190 ","VA-4028 ","EH-1247 ","MS-7018 "] | ["60.00","67.00","22.00","14.99"] | ["bob@example,com","robert.jones@example.com"]
111-952000 | 342845 | ["ID-2586 ","IC-9010 ","MH-2401 ","JC-1905 "] | ["22.00","35.00",null,"12.00"] | ["br92@cs.example.edu"]
111-345634 | 342536 | ["RS-0731 ","SJ-2021 "] | ["50.00",null] | [null]
113-965086 | 342176 | ["GW-1808 "] | ["108.00"] | ["joe.smith@example.com"]
111-335121 | 342321 | ["TF-3556 "] | ["50.00"] | ["789123@example-isp.com","alexjohnson@example.com","monica@eng.example.com","sara@johnson.example.name",null]
(5 rows)
此示例按升序扩展指定客户的 orderprices
列。custkey
和 email_addrs
列对每个数组元素重复。
=> SELECT EXPLODE(orderprices, custkey, email_addrs) OVER(PARTITION BEST) AS (position, orderprices, custkey, email_addrs)
FROM orders WHERE custkey='342845' ORDER BY orderprices;
position | orderprices | custkey | email_addrs
----------+-------------+---------+------------------------------
2 | | 342845 | ["br92@cs.example.edu",null]
3 | 12.00 | 342845 | ["br92@cs.example.edu",null]
0 | 22.00 | 342845 | ["br92@cs.example.edu",null]
1 | 35.00 | 342845 | ["br92@cs.example.edu",null]
(4 rows)
展开包含空值的列时,null 值显示为空。
您可以通过指定 explode_count
参数来展开多个列。
=> SELECT EXPLODE(orderkey, prodkey, orderprices USING PARAMETERS explode_count=2)
OVER(PARTITION BEST)
AS (orderkey,pk_idx,pk_val,ord_idx,ord_val)
FROM orders
WHERE orderkey='113-341987';
orderkey | pk_idx | pk_val | ord_idx | ord_val
------------+--------+----------+---------+---------
113-341987 | 0 | MG-7190 | 0 | 60.00
113-341987 | 0 | MG-7190 | 1 | 67.00
113-341987 | 0 | MG-7190 | 2 | 22.00
113-341987 | 0 | MG-7190 | 3 | 14.99
113-341987 | 1 | VA-4028 | 0 | 60.00
113-341987 | 1 | VA-4028 | 1 | 67.00
113-341987 | 1 | VA-4028 | 2 | 22.00
113-341987 | 1 | VA-4028 | 3 | 14.99
113-341987 | 2 | EH-1247 | 0 | 60.00
113-341987 | 2 | EH-1247 | 1 | 67.00
113-341987 | 2 | EH-1247 | 2 | 22.00
113-341987 | 2 | EH-1247 | 3 | 14.99
113-341987 | 3 | MS-7018 | 0 | 60.00
113-341987 | 3 | MS-7018 | 1 | 67.00
113-341987 | 3 | MS-7018 | 2 | 22.00
113-341987 | 3 | MS-7018 | 3 | 14.99
(16 rows)
以下示例使用多维数组:
=> SELECT name, pingtimes FROM network_tests;
name | pingtimes
------+-------------------------------------------------------
eng1 | [[24.24,25.27,27.16,24.97],[23.97,25.01,28.12,29.5]]
eng2 | [[27.12,27.91,28.11,26.95],[29.01,28.99,30.11,31.56]]
qa1 | [[23.15,25.11,24.63,23.91],[22.85,22.86,23.91,31.52]]
(3 rows)
=> SELECT EXPLODE(name, pingtimes USING PARAMETERS explode_count=1) OVER()
FROM network_tests;
name | position | value
------+----------+---------------------------
eng1 | 0 | [24.24,25.27,27.16,24.97]
eng1 | 1 | [23.97,25.01,28.12,29.5]
eng2 | 0 | [27.12,27.91,28.11,26.95]
eng2 | 1 | [29.01,28.99,30.11,31.56]
qa1 | 0 | [23.15,25.11,24.63,23.91]
qa1 | 1 | [22.85,22.86,23.91,31.52]
(6 rows)
接受任何标量类型的一列并返回一个无界数组。结合 GROUP BY,此函数可用于反转 EXPLODE 操作。
IMPLODE (input-column [ USING PARAMETERS param=value[,...] ] )
[ within-group-order-by-clause ]
WITHIN GROUP (ORDER BY { column-expression[ sort-qualifiers ] }[,...])
sort-qualifiers: { ASC | DESC [ NULLS { FIRST | LAST | AUTO } ] }
allow_truncate
即使此参数设置为 true,如果任何单个数组元素过大,IMPLODE 也会返回错误。截断从输出数组中移除元素,但不改变单个元素。
max_binary_size
考虑使用包含以下内容的表:
=> SELECT * FROM filtered;
position | itemprice | itemkey
----------+-----------+---------
0 | 14.99 | 345
0 | 27.99 | 567
1 | 18.99 | 567
1 | 35.99 | 345
2 | 14.99 | 123
(5 rows)
以下查询调用 IMPLODE 将价格组合为数组(按键分组):
=> SELECT itemkey AS key, IMPLODE(itemprice) AS prices
FROM filtered GROUP BY itemkey ORDER BY itemkey;
key | prices
-----+-------------------
123 | ["14.99"]
345 | ["35.99","14.99"]
567 | ["27.99","18.99"]
(3 rows)
您可以通过包括 WITHIN GROUP ORDER BY 子句来修改此查询,该子句指定如何对每个组中的数组元素进行排序:
=> SELECT itemkey AS key, IMPLODE(itemprice) WITHIN GROUP (ORDER BY itemprice) AS prices
FROM filtered GROUP BY itemkey ORDER BY itemkey;
key | prices
-----+-------------------
123 | ["14.99"]
345 | ["14.99","35.99"]
567 | ["18.99","27.99"]
(3 rows)
有关更完整的示例,请参阅数组和集(集合)。
返回包含两个输入集的所有元素的 SET。
如果输入都是有界限的,则结果的界限是输入的界限之和。
如果任何输入均无界限,则结果是无界限的,其二进制大小是输入大小的总和。
SET_UNION(set1,set2)
空实参会被忽略。如果输入之一为空,则函数返回非空输入。换言之,NULL 的实参等价于 SET[]。
如果两个输入均为空值,则函数返回 null。
=> SELECT SET_UNION(SET[1,2,4], SET[2,3,4,5.9]);
set_union
-----------------------
["1.0","2.0","3.0","4.0","5.9"]
(1 row)
拆分包含数组值的字符串并返回原生一维数组。输出不包括“ARRAY”关键字。此函数不支持嵌套(多维)数组。
默认情况下,此函数将数组元素作为字符串返回。您可以转换为其他类型,如下例所示:
=> SELECT STRING_TO_ARRAY('[1,2,3]')::ARRAY[INT];
STRING_TO_ARRAY(string [USING PARAMETERS param=value[,...]])
以下语法已弃用:
STRING_TO_ARRAY(string, delimiter)
除非元素被单独引用,否则字符串中的空格将被移除。例如,' a,b,c'
等价于 'a,b,c'
。要保留空间,请使用 '" a","b","c"'
。
这些参数的行为方式与加载分隔数据时的相应选项相同(请参阅 DELIMITED)。
任何参数不得与任何其他参数具有相同的值。
collection_delimiter
默认值: 逗号 (',')。
collection_open
, collection_close
默认值: 方括号('[' 和 ']')。
collection_null_element
默认值: 'null'
collection_enclose
默认: 双引号('"')
该函数使用逗号作为默认分隔符。您可以指定不同的值:
=> SELECT STRING_TO_ARRAY('[1,3,5]');
STRING_TO_ARRAY
-----------------
["1","3","5"]
(1 row)
=> SELECT STRING_TO_ARRAY('[t|t|f|t]' USING PARAMETERS collection_delimiter = '|');
STRING_TO_ARRAY
-------------------
["t","t","f","t"]
(1 row)
边界括号是可选的:
=> SELECT STRING_TO_ARRAY('t|t|f|t' USING PARAMETERS collection_delimiter = '|');
STRING_TO_ARRAY
-------------------
["t","t","f","t"]
(1 row)
输入可以使用其他字符进行打开和关闭:
=> SELECT STRING_TO_ARRAY('{NASA-1683,NASA-7867,SPX-76}' USING PARAMETERS collection_open = '{', collection_close = '}');
STRING_TO_ARRAY
------------------------------------
["NASA-1683","NASA-7867","SPX-76"]
(1 row)
默认情况下,输入中的字符串 'null' 被视为空值:
=> SELECT STRING_TO_ARRAY('{"us-1672",null,"darpa-1963"}' USING PARAMETERS collection_open = '{', collection_close = '}');
STRING_TO_ARRAY
-------------------------------
["us-1672",null,"darpa-1963"]
(1 row)
在以下示例中,输入来自列:
=> SELECT STRING_TO_ARRAY(name USING PARAMETERS collection_delimiter=' ') FROM employees;
STRING_TO_ARRAY
-----------------------
["Howard","Wolowitz"]
["Sheldon","Cooper"]
(2 rows)
返回复杂类型实参的 JSON 表示,包括混合和嵌套的复杂类型。这与复杂类型列的查询返回的格式相同。
TO_JSON(value)
这些示例查询下表:
=> SELECT name, contact FROM customers;
name | contact
--------------------+-----------------------------------------------------------------------------------------------------------------------
Missy Cooper | {"street":"911 San Marcos St","city":"Austin","zipcode":73344,"email":["missy@mit.edu","mcooper@cern.gov"]}
Sheldon Cooper | {"street":"100 Main St Apt 4B","city":"Pasadena","zipcode":91001,"email":["shelly@meemaw.name","cooper@caltech.edu"]}
Leonard Hofstadter | {"street":"100 Main St Apt 4A","city":"Pasadena","zipcode":91001,"email":["hofstadter@caltech.edu"]}
Leslie Winkle | {"street":"23 Fifth Ave Apt 8C","city":"Pasadena","zipcode":91001,"email":[]}
Raj Koothrappali | {"street":null,"city":"Pasadena","zipcode":91001,"email":["raj@available.com"]}
Stuart Bloom |
(6 rows)
您可以在列或特定字段或数组元素上调用 TO_JSON:
=> SELECT TO_JSON(contact) FROM customers;
to_json
-----------------------------------------------------------------------------------------------------------------------
{"street":"911 San Marcos St","city":"Austin","zipcode":73344,"email":["missy@mit.edu","mcooper@cern.gov"]}
{"street":"100 Main St Apt 4B","city":"Pasadena","zipcode":91001,"email":["shelly@meemaw.name","cooper@caltech.edu"]}
{"street":"100 Main St Apt 4A","city":"Pasadena","zipcode":91001,"email":["hofstadter@caltech.edu"]}
{"street":"23 Fifth Ave Apt 8C","city":"Pasadena","zipcode":91001,"email":[]}
{"street":null,"city":"Pasadena","zipcode":91001,"email":["raj@available.com"]}
(6 rows)
=> SELECT TO_JSON(contact.email) FROM customers;
to_json
---------------------------------------------
["missy@mit.edu","mcooper@cern.gov"]
["shelly@meemaw.name","cooper@caltech.edu"]
["hofstadter@caltech.edu"]
[]
["raj@available.com"]
(6 rows)
使用 SET 调用 TO_JSON 时,请注意移除重复项并且可以重新排序元素:
=> SELECT TO_JSON(SET[1683,7867,76,76]);
TO_JSON
----------------
[76,1683,7867]
(1 row)