这是本节的多页打印视图。 点击此处打印.

返回本页常规视图.

表达式

SQL 表达式是将某个值或多个值与其他值进行比较的查询的组件。它们还可以执行计算。在任何 SQL 命令中发现的表达式通常采用条件语句的形式。

运算符优先级

下表按递减(由高到低)顺序显示运算符优先级。

表达式求值规则

未定义子表达式的求值顺序。特别是,不必由左到右或以任何其他固定顺序对运算符或函数输入进行求值。要强制按特定顺序进行求值,请使用 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 表达式是一个通用条件表达式,可在表达式有效的情况下使用。它与其他语言的 CASEIF/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 解析日期/时间类型输入内容如下:

  1. 将输入字符串拆分为标记,并将每个标记分类为字符串、时间、时区或数字。

  2. 数字标记包含:

    • 冒号 (:)- 解析为时间字符串,包括所有后续数字和冒号。

    • 破折号 (-)、斜杠 (/) 或者两个或更多的点 (.)- 解析为日期字符串,可能包含文本月份。

    • 仅数字 - 解析为单一字段或 ISO 8601 串联日期(19990113 表示 1999 年 1 月 13 日)或时间(141516 表示 14:15:16)。

  3. 以加号 (+) 或减号 (–) 作为开头的标记:解析为时区或特殊字段。

  4. 标记是文本字符串:与可能的字符串相匹配。

    • 使用二分搜索表查找标记,特殊字符串(例如今日)、星期(例如星期四)、月份(例如一月)或干扰词(例如 at、on)。

    • 设置字段的字段值和位掩码。例如,设置今日对应的年、月、日,还有当前的小时、分钟、秒钟。

    • 如果未找到,进行类似的二分搜索表查询,将标记与时区进行匹配。

    • 如果仍未找到,则会收到错误消息。

  5. 标记可以是一个数字或数字字段:

    • 如果是 8 位或 6 位数,且之前没有读取其他日期字段,则解释为“串联日期”(19990118 或 990118)。此解释为 YYYYMMDD YYMMDD

    • 如果标记是三位数,并且已经读取了年份,则解释为一年中的第几日。

    • 如果标记是四位或六位数,并且已经读取了年份,则解释为时间(HHMMHHMMSS)。

    • 如果是三位或更多位数,且未找到日期字段,则解释为年份(这样会强制剩余的日期字段按“年-月-日”的格式排序)。

    • 否则,假定日期字段排序遵循 DateStyle 设置:月-日-年、日-月-年或年-月-日。如果发现月份或日期字段超出范围,则会收到错误消息。

  6. 如果已指定 BC:忽略年份并添加一个用于内部存储。(在 Vertica 实施中,1 BC = 元年。)

  7. 如果未指定 BC,且年份字段是两位长度:将年份调整为四位数。如果字段小于 70,则添加 2000,否则添加 1900。

年月日排序

对于某些格式,年、月、日的日期输入排序不明确,可支持指定这些字段的预期排序。

特殊日期/时间值

为了方便起见,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 处理函数