|
1.3. 值表达式值表达式用在各种语法环境中,比如在 SELECT 命令的目标列表中,在 INSERT 或 UPDATE 中用做新的列值,或者在许多命令中的 搜索条件中使用. 我们有时候把值表达式的结果叫做 标量 , 以便与一个表表达式的结果相区别(是一个表).因此值表达式也叫做 标量表达式 (或者更简单的 表达式 ).表达式语法允许对来自基本部分的 数值进行算术,逻辑,集合,和其它操作的运算. 值表达式是下列内容之一:
除了这个列表以外,还有许多构造可以归类为表达式,但是不遵循任何 通用的语法规则. 它们通常有函数或操作符的语义,并且在 Chapter 4 里合适的位置描述. 一个例子是 IS NULL 子句. 我们已经在 Section 1.1.2 里有讨论过的 内容了.下面的节讨论剩下的选项. 1.3.1. 字段引用一个字段可以是下面形式的引用: correlation . columnname `[' subscript `]' correlation 要么是一个表的名字, 要么是用 FROM 子句这样的方法定义的表的别名,或者是关键字 NEW 或 OLD . (NEW 和 OLD 只能出现在一条规则的动作部分, 而其他相关的名字可以用于任意 SQL 语句中.) 如果在当前查询中所使用的所有表中,该字段名字是唯一的, 那么这个相关名字和分隔用的点就可以省略.如果 column 是一个数组类型,那么可选的 subscript 选择该数组中指定的一个或多个元素. 如果没有提供脚标,那么选出整个数组.(请参考 Chapter 6 获取关于数组的更多信息.) 1.3.2. 位置参数位置参数引用用于标识一个 SQL 函数里的一个参数. 通常它用于 SQL 函数定义语句.一个参数的形式如下: $ number
比如,看看一个函数 dept 的定义, 如下 CREATE FUNCTION dept (text) RETURNS dept AS 'SELECT * FROM dept WHERE name = $1' LANGUAGE SQL; 在函数被调用的时候这里的 $1 将被第一个函数的参数代替. 1.3.3. 操作符调用操作符调用有三种语法∶
这里的 operator 记号遵循语法规则∶ Section 1.1.3 或者是记号∶ AND , OR ,和 NOT 之一. 具体存在哪个操作符以及它们是单目还是双目取决于系统或用户 定义了什么操作符. Chapter 4 描述了内建的操作符. 1.3.4. 函数调用函数调用的语法是合法函数名字(受标识符语法规则的约束 Section 1.1.1 ),后面跟着在圆括弧里 的它的参数列表:
function
([
expression
[
,
expression
...
]
] )
比如,下面的代码计算 2 的平方根: sqrt(2)
内建函数的列表在 Chapter 4 里. 其它函数可以由用户添加. 1.3.5. 聚集表达式一个 聚集表达式 代表一个聚集函数对 一个查询选出的行的处理.一个聚集函数把多个输入缩减为一个输出值, 比如给输入求和或平均.一个聚集表达式的语法是下列之一:
这里 aggregate_name 是前面定义的聚集, 而 expression 是一个本身不包含聚集表达式 的任意值表达式. 第一种形式的聚集表达式为所有表达式生成非空值的输入行调用聚集. (实际上,是否忽略空值由聚集函数决定 --- 但是所有标准的聚集 函数都忽略它们.) 第二种形式和第一种一样,因为 ALL 是缺省值.第三种形式为所有输入行里找到 表达式的所有唯一的非空值调用聚集. 最后一种形式为每个输入行(不管是空还是非空)调用一次聚集; 因为没有声明特定的输入值.通常它只是对 count() 聚集函数有用. 比如, count(*) 生成输入行的总数; count(f1) 生成 f1 为非空的 输入行数; count(distinct f1) 生成 f1 唯一非空的行数. 预定义的聚集函数在 Section 4.14 里描述. 其它聚集函数可以由用户增加. 1.3.6. 类型转换一个类型转换声明一个从一种数据类型到另外一种数据类型的转换. PostgreSQL 接受两种等效的类型转换语法∶ CAST ( expression AS type ) expression :: type CAST 语法遵循 SQL92; :: 的语法是 PostgreSQL 传统用法. 如果对一个已知类型的值表达式应用转换,它代表一个运行时类型转换. 只有在存在合适的类型转换函数的情况下,该转换才能成功. 请注意这一点和用于常量的转换略有区别,如 Section 1.1.2.5 所示. 一个应用于某个未修饰的字串文本的转换表示给一个字串文本数值赋予一个 初始化类型,因此它对于任何类型都会成功(如果字串文本的内容符合 该数据类型的输入语法接受.) 如果对于一个值表达式生成的数值对某类型而言不存在混淆的情况, 那么我们可以省略类型转换(比如,在给一个表字段赋值的时候); 在这样的情况下,系统将自动附加一个类型转换. 我们也可以用函数样的语法声明一个类型转换∶ typename ( expression ) 不过,这个方法只能用于那些名字同时也是有效函数名字的类型. 比如, double precision 就不能这么用, 但是等效的 float8 可以.同样, interval , time ,和 timestamp 如果加了双引号也只能 这么用,因为存在分析器冲突.因此,函数样的类型转换会导致不一致, 所以可能应该避免这么用. 1.3.7. 标量子查询一个标量子查询是一个放在圆括弧里的普通 SELECT , 它只返回只有一个字段的一行.该 SELECT 将被执行, 而其单个返回值将在周围的值表达式中使用. 把一个返回超过一行或者超过一列的查询用做标量查询是错误的. (不过,在特定的执行中,子查询不返回行则不算错误;标量结果认为是 NULL.)该子查询可以引用周围查询的变量, 那些变量也是在计算任意子查询的时候当做常量使用的. 又见 Section 4.15 . 比如,下面的查询找出每个州中的最大人口数量的城市∶ SELECT name, (SELECT max(pop) FROM cities WHERE cities.state = states.name) FROM states;
|