这是本节的多页打印视图。
点击此处打印.
返回本页常规视图.
表达式
SQL 表达式是将某个值或多个值与其他值进行比较的查询的组件。它们还可以执行计算。在任何 SQL 命令中发现的表达式通常采用条件语句的形式。
运算符优先级
下表按递减(由高到低)顺序显示运算符优先级。
注意
当表达式包含多个运算符时,Vertica 建议您使用括号指定运算顺序,而不是依赖运算符优先级。
表达式求值规则
未定义子表达式的求值顺序。特别是,不必由左到右或以任何其他固定顺序对运算符或函数输入进行求值。要强制按特定顺序进行求值,请使用 CASE
构造。例如,这是一种在 WHERE
子句中尝试避免除数为零的不受信任方式:
=> SELECT x, y WHERE x <> 0 AND y/x > 1.5;
但这种方式比较安全:
=> SELECT x, y
WHERE
CASE
WHEN x <> 0 THEN y/x > 1.5
ELSE false
END;
此方式中使用的 CASE
构造会导致优化尝试失败,因此仅在必要时使用。(在这个特定示例中,最好改为写入 y > 1.5*x
以避免相关问题。)
SQL 表达式的限制
对于您可在表达式中使用的修饰符和递归的数量,存在一些限制。您应该注意以下两项限制:
-
第一项限制基于可供表达式使用的堆栈。Vertica 需要至少 100kb 的可用堆栈。如果超出此限制,则可能引发错误“查询包含的表达式过于复杂而无法分析 (The query contains an expression that is too complex to analyze)”。额外增加物理内存和/或增大 ulimit -s
max 值可增加可用堆栈并防止错误。
-
第二项限制为分析表达式中可能的递归数。上限为 2000。如果超出此限制,则可能引发错误“查询包含的表达式过于复杂而无法分析 (The query contains an expression that is too complex to analyze)”。此限制无法提高。
1 - 聚合表达式
聚合表达式在查询选定的各个行或行组中应用聚合函数。
聚合表达式只能出现在选择列表中或 HAVING
语句的 SELECT
子句中。它在其他子句(如 WHERE
)中无效,因为这些子句是在聚合结果形成之前进行评估的。
语法
聚合表达式的格式如下:
aggregate‑function ( [ * ] [ ALL | DISTINCT ] expression )
参数
示例
AVG 聚合函数返回 customer_dimension 表中的平均收入:
=> SELECT AVG(annual_income) FROM customer_dimension;
AVG
--------------
2104270.6485
(1 row)
以下示例显示了如何使用具有 DISTINCT 关键字的 COUNT 聚合函数返回对所有 inventory_fact 记录计算表达式 x+y 得到的所有不同值。
=> SELECT COUNT (DISTINCT date_key + product_key) FROM inventory_fact;
COUNT
-------
21560
(1 row)
2 - CASE 表达式
CASE
表达式是一个通用条件表达式,可在表达式有效的情况下使用。它与其他语言的 CASE
和 IF/THEN/ELSE
语句相似。
语法(第一种形式)
CASE
WHEN condition THEN result
[ WHEN condition THEN result ]
...
[ ELSE result ]
END
参数
语法(第二种形式)
CASE expression
WHEN value THEN result
[ WHEN value THEN result ]
...
[ ELSE result ]
END
参数
注意
所有 result 表达式的数据类型必须可转换为一个输出类型。
示例
以下示例显示了 CASE
语句的两种使用方法。
=> SELECT * FROM test;
a
---
1
2
3
=> SELECT a,
CASE WHEN a=1 THEN 'one'
WHEN a=2 THEN 'two'
ELSE 'other'
END
FROM test;
a | case
---+-------
1 | one
2 | two
3 | other
=> SELECT a,
CASE a WHEN 1 THEN 'one'
WHEN 2 THEN 'two'
ELSE 'other'
END
FROM test;
a | case
---+-------
1 | one
2 | two
3 | other
特殊示例
CASE
表达式不会对无需确定结果的子表达式求值。您可以使用此行为来避免被零除错误:
=> SELECT x FROM T1 WHERE
CASE WHEN x <> 0 THEN y/x > 1.5
ELSE false
END;
3 - 列引用
语法
[[[database.]schema.]table-name.]column-name
参数
限制
列引用不能包含任何空格。
4 - 注释
注释为任意字符序列,以两个连续的连字符开头并延伸到行的结尾。例如:
-- This is a standard SQL comment
先从输入流中移除注释再执行进一步的语法分析,并有效替换为空格。
或者,也可以使用 C 样式块注释,其中注释以 /*
开头并延伸到匹配出现的 */
。
/* multiline comment
* with nesting: /* nested block comment */
*/
这些块注释根据 SQL 标准中指定的方法嵌套。与 C 不同,您可以注释掉可能包含现有块注释的较大代码块。
5 - 日期/时间表达式
Vertica 将内部启发式解析器用于全部日期/时间输入支持。日期和时间以字符串输入,通过初步确定字段中可能存在的信息种类,拆分为不同字段。每个字段均被解释并分配数值,或者被忽略或拒绝。解析器包含所有文本字段的内部查询表,包括月份、星期和时区。
Vertica 解析日期/时间类型输入内容如下:
-
将输入字符串拆分为标记,并将每个标记分类为字符串、时间、时区或数字。
-
数字标记包含:
-
冒号 (:)- 解析为时间字符串,包括所有后续数字和冒号。
-
破折号 (-)、斜杠 (/) 或者两个或更多的点 (.)- 解析为日期字符串,可能包含文本月份。
-
仅数字 - 解析为单一字段或 ISO 8601 串联日期(19990113 表示 1999 年 1 月 13 日)或时间(141516 表示 14:15:16)。
-
以加号 (+) 或减号 (–) 作为开头的标记:解析为时区或特殊字段。
-
标记是文本字符串:与可能的字符串相匹配。
-
使用二分搜索表查找标记,特殊字符串(例如今日)、星期(例如星期四)、月份(例如一月)或干扰词(例如 at、on)。
-
设置字段的字段值和位掩码。例如,设置今日对应的年、月、日,还有当前的小时、分钟、秒钟。
-
如果未找到,进行类似的二分搜索表查询,将标记与时区进行匹配。
-
如果仍未找到,则会收到错误消息。
-
标记可以是一个数字或数字字段:
-
如果是 8 位或 6 位数,且之前没有读取其他日期字段,则解释为“串联日期”(19990118 或 990118)。此解释为 YYYYMMDD
或 YYMMDD
。
-
如果标记是三位数,并且已经读取了年份,则解释为一年中的第几日。
-
如果标记是四位或六位数,并且已经读取了年份,则解释为时间(HHMM
或 HHMMSS
)。
-
如果是三位或更多位数,且未找到日期字段,则解释为年份(这样会强制剩余的日期字段按“年-月-日”的格式排序)。
-
否则,假定日期字段排序遵循 DateStyle
设置:月-日-年、日-月-年或年-月-日。如果发现月份或日期字段超出范围,则会收到错误消息。
-
如果已指定 BC:忽略年份并添加一个用于内部存储。(在 Vertica 实施中,1 BC = 元年。)
-
如果未指定 BC,且年份字段是两位长度:将年份调整为四位数。如果字段小于 70,则添加 2000,否则添加 1900。
提示
公历年 AD 1–99 可按 4 位数输入,开头加零,例如,0099 = AD 99。
年月日排序
对于某些格式,年、月、日的日期输入排序不明确,可支持指定这些字段的预期排序。
特殊日期/时间值
为了方便起见,Vertica 支持数个特殊日期/时间值,如下所示。当用作 SQL 语句中的常数时,所有这些值在书写时都需要加单引号。
值 INFINITY
和 -INFINITY
在系统中以特殊形式表示,并以相同方式显示。其他值为读取时转换为普通日期/时间值的简写符号。(尤其是,NOW
和相关字符串在读取后立即转换为特定时值。)
以下兼容 SQL 的函数也可用于获取相应数据类型的当前时间值。
后四个接受可选的精度要求。(请参阅日期/时间函数。)然而,这些函数是 SQL 函数,不能识别为数据输入字符串。
6 - NULL 值
NULL 是一个保留关键字,用于表示未知的数据值。它是 NULL 字符 (\0
) 的 ASCII 缩写。
表达式中的使用情况
Vertica 不会将空字符串视为 NULL 值。表达式必须指定 NULL 才能表示列值未知。
以下注意事项适用于在表达式中使用 NULL:
-
NULL 不大于、小于、等于或不等于任何其他表达式。使用 布尔谓词 确定一个表达式的值是否为 NULL。
-
您可以通过含有 NULL=NULL
联接的 <=>
运算符的表达式编写查询。请参阅等联接和非等联接。
-
Vertica 接受常量字符串中的 NULL 字符 ('\0'
),且并未从输入或输出的 VARCHAR 字段移除 NULL 字符。
NULL 数据的投影排序
Vertica 对投影列中的 NULL 值进行排序,如下所示:
另请参阅
NULL 处理函数