运算符是指为求值、比较或计算值而在 SQL 中使用的逻辑、数学和等式符号。
运算符
- 1: 位运算符
- 2: 布尔运算符
- 3: 比较运算符
- 4: 数据类型强制运算符 (CAST)
- 4.1: 转换失败
- 5: 日期/时间运算符
- 6: 数学运算符
- 7: NULL 运算符
- 8: 字符串串联运算符
1 - 位运算符
位运算符对 INTEGER 和 BINARY/VARBINARY 数据类型执行位操作:
†对 BINARY/VARBINARY 数据类型无效
字符串实参处理
对于所有位运算符,必须将字符串实参显式转换为 BINARY 或 VARBINARY 数据类型。例如:
=> SELECT 'xyz'::VARBINARY & 'zyx'::VARBINARY AS AND;
AND
-----
xyx
(1 row)
=> SELECT 'xyz'::VARBINARY | 'zyx'::VARBINARY AS OR;
OR
-----
zyz
(1 row)
位运算符将所有字符串实参视为长度相同。如果实参长度不同,则运算符函数会使用一个或多个零字节右侧填充较小的字符串,使其长度与较大的字符串相同。
例如,以下语句 AND 长度不同的字符串 xyz
和 zy
。Vertica 使用一个零字节右侧填充字符串 zy
。相应地,结果中的最后一个字符表示为 \000
:
=> SELECT 'xyz'::VARBINARY & 'zy'::VARBINARY AS AND;
AND
--------
xy\000
(1 row)
2 - 布尔运算符
Vertica 支持以下布尔运算符:
-
AND
-
OR
-
NOT
运算符 AND
和 OR
可交换,也就是说,可以在不影响结果的情况下切换左右操作数。但是,未定义子表达式的求值顺序。要强制执行求值顺序,请使用 CASE 构造。
逻辑
SQL 使用三值布尔逻辑,其中 NULL
表示“未知”。
3 - 比较运算符
只要比较有意义,比较运算符可适用于所有数据类型。所有比较运算符均为二元运算符,可返回 true、false 或 NULL 这些值。
NULL 处理
如果一个或两个操作数为 NULL,则比较运算符返回 NULL。存在一个例外: <=>
如果两个操作数都为 NULL,则返回 true;如果一个操作数为 NULL,则返回 false。
集合
当对集合进行比较时,NULL 集合排在最后。否则,逐个元素比较集合,直到出现不匹配,然后根据不匹配的元素对它们进行排序。如果所有元素的长度都依次等于较短的元素的长度,则首先排序较短的元素。
4 - 数据类型强制运算符 (CAST)
数据类型强制转换(转换)将表达式的值传递给输入转换例程以转换为指定的数据类型,得到指定类型的常数。在 Vertica 中,可以通过使用以下结构之一的显式转换请求来调用数据类型强制功能:
语法
SELECT CAST ( expression AS data‑type )
SELECT expression::data‑type
SELECT data‑type 'string'
参数
截断
如果将二进位值转换(隐式或显式)为较小长度的二进位类型,该值将被自动截断。例如:
=> SELECT 'abcd'::BINARY(2);
?column?
----------
ab
(1 row)
类似地,如果将字符值转换(隐式或显式)为较小长度的字符值,该值将被自动截断。例如:
=> SELECT 'abcd'::CHAR(3);
?column?
----------
abc
(1 row)
二进制转换和调整大小
Vertica 仅支持以下转换和调整大小操作:
-
从 BINARY 转换到和转换自 VARBINARY
-
从 VARBINARY 转换到和转换自 LONG VARBINARY
-
从 BINARY 转换到和转换自 LONG VARBINARY
对于包含少于目标列字节的值的二进位数据,零字节 '\0'
的值向右扩展为整个列宽。可变长度的二进位值的尾随零不能向右扩展:
=> SELECT 'ab'::BINARY(4), 'ab'::VARBINARY(4), 'ab'::LONG VARBINARY(4);
?column? | ?column? | ?column?
------------+----------+----------
ab\000\000 | ab | ab
(1 row)
自动强制
如果常数类型明确,可以忽略显式类型转换。例如,直接分配常数到一列中,该常数会自动强制转换为该列的数据类型。
示例
=> SELECT CAST((2 + 2) AS VARCHAR);
?column?
----------
4
(1 row)
=> SELECT (2 + 2)::VARCHAR;
?column?
----------
4
(1 row)
=> SELECT INTEGER '123';
?column?
----------
123
(1 row)
=> SELECT (2 + 2)::LONG VARCHAR
?column?
----------
4
(1 row)
=> SELECT '2.2' + 2;
ERROR: invalid input syntax for integer: "2.2"
=> SELECT FLOAT '2.2' + 2;
?column?
----------
4.2
(1 row)
另请参阅
4.1 - 转换失败
当您通过显式转换调用数据类型转换(转换),但该转换失败时,结果将返回错误或 NULL。当您尝试进行冲突的转换时,如尝试将包含字母的 VARCHAR 表达式转换为整数,通常就会发生转换失败。
当转换失败时,返回的结果取决于数据类型。
启用严格的时间转换
您可以使所有转换失败产生错误,包括针对日期/时间数据类型的转换。这样做将使您能查看某些或所有转换失败的原因。要返回错误而不是 NULL,请将配置参数 EnableStrictTimeCasts 设置为 1:
ALTER SESSION SET EnableStrictTimeCasts=1;
默认情况下,EnableStrictTimeCasts 设置为 0。因此,以下尝试将 VARCHAR 转换为 TIME 数据类型的行为返回 NULL:
==> SELECT current_value from configuration_parameters WHERE parameter_name ilike '%EnableStrictTimeCasts%';
current_value
---------------
0
(1 row)
=> CREATE TABLE mytable (a VARCHAR);
CREATE TABLE
=> INSERT INTO mytable VALUES('one');
OUTPUT
--------
1
(1 row)
=> INSERT INTO mytable VALUES('1');
OUTPUT
--------
1
(1 row)
=> COMMIT;
COMMIT
=> SELECT a::time FROM mytable;
a
---
(2 rows)
如果启用 EnableStrictTimeCasts,则转换失败返回错误:
=> ALTER SESSION SET EnableStrictTimeCasts=1;
ALTER SESSION
=> SELECT a::time FROM mytable;
ERROR 3679: Invalid input syntax for time: "1"
使所有转换失败返回 NULL
要将某一表达式显式转换为请求的数据类型,请使用以下结构:
SELECT expression::data-type
使用此命令将任何值转换为冲突的数据类型,将返回以下错误:
=> SELECT 'one'::time;
ERROR 3679: Invalid input syntax for time: "one"
Vertica 也支持使用强制转换运算符 ::!
,当希望返回以下结果时很有用:
-
对于非日期/时间数据类型,返回 NULL 而不是错误
-
在设置 EnableStrictTimeCasts 后,返回 NULL 而不是错误
使所有转换失败返回 NULL 可使在转换期间成功的表达式显示在结果中。但在转换期间失败的表达式将产生 NULL 值。
以下示例使用强制转换运算符 ::!
查询 mytable
。查询返回 NULL,其中列 a
包含字符串 one
;返回 1
,其中列包含 1
。无论如何设置 EnableStrictTimeCasts,查询结果都相同:
=> SELECT current_value FROM configuration_parameters WHERE parameter_name ilike '%EnableStrictTimeCasts%';
current_value
---------------
0
(1 row)
=> SELECT a::!int FROM mytable;
a
---
1
(2 rows)
ALTER SESSION SET EnableStrictTimeCasts=1;
ALTER SESSION
=> SELECT a::!int FROM mytable;
a
---
1
(2 rows)
您可以使用 ::!
转换数组和集合。转换单独解析每个元素,为无法转换的元素生成 NULL。
5 - 日期/时间运算符
语法
[ + | – | * | / ]
参数
+ Addition
– Subtraction
* Multiplication
/ Division
注意
-
下文描述的
TIME
或TIMESTAMP
输入运算符其实有两种变体:一种是TIME WITH TIME ZONE
或TIMESTAMP WITH TIME ZONE
;另一种是TIME WITHOUT TIME ZONE
或TIMESTAMP WITHOUT TIME ZONE
。简洁起见,这些变体不单独显示。 -
+
和*
运算符以交换对的形式出现(例如DATE
+INTEGER
和INTEGER
+DATE
);每个交换对仅显示其中一个运算符。
6 - 数学运算符
为很多数据类型提供数学运算符。
阶乘运算符支持
Vertica 支持对正负浮点 (DOUBLE PRECISION
) 数和整数使用阶乘运算符。例如:
=> SELECT 4.98!;
?column?
------------------
115.978600750905
(1 row)
阶乘在 gamma 函数的术语中定义,其中 (-1) = 无限,其他负整数未定义。例如:
(–4)! = NaN
–(4!) = –24
对于所有复数 z,阶乘定义如下:
z! = gamma(z+1)
有关详细信息,请参阅 Abramowitz 和 Stegun:数学函数手册。
7 - NULL 运算符
要检查某个值是否为 NULL
,请使用以下构造:
[expression IS NULL | expression IS NOT NULL]
或者,使用等效(但非标准)构造:
[expression ISNULL | expression NOTNULL]
不要写入 expression = NULL
,因为 NULL
表示未知值,两个未知值不一定相等。此行为遵守 SQL 标准。
注意
如果 expression 求值结果为 NULL,则某些应用程序可能预期 expression = NULL 返回 true。Vertica 强烈建议修改这些应用程序,以便遵守 SQL 标准。8 - 字符串串联运算符
要串联同一行的两个字符串,请使用串联运算符(两条连续的竖线)。
语法
string || string
参数
注意
-
|| 用于串联表达式和常量.表达式应尽可能投射至
VARCHAR
,否则就投射至VARBINARY
,而且必须投射至其中一个。 -
单个 SQL 语句中的两个连续字符串在不同行会自动串联
示例
以下示例是位于两行的单个字符串:
=> SELECT E'xx'-> '\\';
?column?
----------
xx\
(1 row)
以下示例显示两个串联的字符串:
=> SELECT E'xx' ||-> '\\';
?column?
----------
xx\\
(1 row)
=> SELECT 'auto' || 'mobile';
?column?
----------
automobile
(1 row)
=> SELECT 'auto'-> 'mobile';
?column?
----------
automobile
(1 row)
=> SELECT 1 || 2;
?column?
----------
12
(1 row)
=> SELECT '1' || '2';
?column?
----------
12
(1 row)
=> SELECT '1'-> '2';
?column?
----------
12
(1 row)