PostgreSQL7.0手册-用户手册-2. SQL 语法
2019-09-08 23:32:56
供稿:网友
第二章. SQL 语法
内容
关键字
注释
名称
常量
域和列(字段)
操作符
表达式
描述通用的 SQL 语法。
SQL 操作数据集。该语言由多种多样的 关键字 组成。它允许使用算术和过程表达式。我们将在本章讨论这个问题;随后的章节将包括一些关于数据类型,函数和操作符的细节。
关键字
SQL92 为这门语言定义了有明确意义的 关键字 。有些关键字是 保留字,表明它们只限于出现在某些特定的环境里。其他关键字是 非限制字,表明它们在某些特定的环境里有特殊含义,否则没有什么限制。
Postgres 实现了一个扩展了的 SQL92 和 SQL3 语言的子集。部分由于 Postgres 的可扩展性,一些语言元素在 Postgres 里的实现不象在语言标准里期望的那样严格(限制)。
关于SQL92 和 SQL3 关键字的信息源自 Date and Darwen, 1997。
保留关键字
SQL92 和 SQL3 有一些 保留关键字 除了在 SQL 语句里面用做基本元素外不允许用做标识或者任何其它用途。Postgres 有另外一些关键字也有类似约束。具体来说,这些关键字不允许用做字段或者表名称,尽管有时候它们可以用做字段标签(例如,在AS子句里)。
小技巧: 如果用双引号包围(“象这样!”),任何字串都可以声明为标识。这时我们要仔细一些,因为这样做一个标识将是大小写敏感的并且将保有嵌入的空白或其他特殊字符。
下面是 Postgres 特有的保留关键字,它们既不是 SQL92 也不是 SQL3 保留字。这些字允许做为字段标记出现,但不允许用作标识:
ABORT ANALYZE
BINARY
CLUSTER CONSTRAINT COPY
DO
EXPLAIN EXTEND
LISTEN LOAD LOCK
MOVE
NEW NONE NOTIFY
OFFSET
RESET
SETOF SHOW
UNLISTEN UNTIL
VACUUM VERBOSE
下面是 Postgres 的保留关键字,同时也是 SQL92 或SQL3 的保留字。这些字允许做为字段标记出现,但不允许用作标识:
ALL ANY ASC BETWEEN BIT BOTH
CASE CAST CHAR CHARACTER CHECK COALESCE COLLATE COLUMN
CONSTRAINT CROSS CURRENT CURRENT_DATE CURRENT_TIME
CURRENT_TIMESTAMP CURRENT_USER
DEC DECIMAL DEFAULT DESC DISTINCT
ELSE END EXCEPT EXISTS EXTRACT
FALSE FLOAT FOR FOREIGN FROM FULL
GLOBAL GROUP
HAVING
IN INNER INTERSECT INTO IS
JOIN
LEADING LEFT LIKE LOCAL
NATURAL NCHAR NOT NULL NULLIF NUMERIC
ON OR ORDER OUTER OVERLAPS
POSITION PRECISION PRIMARY PUBLIC
REFERENCES RIGHT
SELECT SESSION_USER SOME SUBSTRING
TABLE THEN TO TRANSACTION TRIM TRUE
UNION UNIQUE USER
VARCHAR
WHEN WHERE
下面是 Postgres 的保留关键字,同时也是 SQL92 或SQL3 的保留字:
ADD ALTER AND AS
BEGIN BY
CASCADE CLOSE COMMIT CREATE CURSOR
DECLARE DEFAULT DELETE DESC DISTINCT DROP
EXECUTE EXISTS EXTRACT
FETCH FLOAT FOR FROM FULL
GRANT
HAVING
IN INNER INSERT INTERVAL INTO IS
JOIN
LEADING LEFT LIKE LOCAL
NAMES NATIONAL NATURAL NCHAR NO NOT NULL
ON OR OUTER
PARTIAL PRIMARY PRIVILEGES PROCEDURE PUBLIC
REFERENCES REVOKE RIGHT ROLLBACK
SELECT SET SUBSTRING
TO TRAILING TRIM
UNION UNIQUE UPDATE USING
VALUES VARCHAR VARYING VIEW
WHERE WITH WORK
下面的是 SQL92 的保留字但不是 Postgres 的保留字,不过如果你把它们做函数名用,就总是会被转换成函数 CHAR_LENGTH:
CHARACTER_LENGTH
下面的是 SQL92 或 SQL3 的保留字但不是 Postgres 的保留字,不过如果你把它们用做类型名,就总是会转换成一个可替换的本机类型:
BOOLEAN DOUBLE FLOAT INT INTEGER INTERVAL REAL SMALLINT
下面的不是任何类型的关键字,不过如果你在一个类型名的环境中使用它们,它们就会转换成一个Postgres 本机类型,而在一个函数名的环境中使用它们,它们会被转换成一个本机函数:
DATETIME TIMESPAN
(相应地转换成 TIMESTAMP 和 INTERVAL)。这个特性用于帮助向 v7.0 转换,将在下一个完全发布版本(估计是 v7.1)删除。
下面的要么是 SQL92 要么是 SQL3 的保留字,但不是 Postgres 的保留字。这些字在写作本章(v7.0)的时候在 Postgres 里面没有使用限制,但是未来有可能成为保留字:
注意: 这里面有些关键字代表 SQL92 里的函数。这些函数在 Postgres 里面有定义。但是分析器不认为(函数)名字是关键字,因而它们可以用在其他环境里。
ALLOCATE ARE ASSERTION AT AUTHORIZATION AVG
BIT_LENGTH
CASCADED CATALOG CHAR_LENGTH CHARACTER_LENGTH COLLATION
CONNECT CONNECTION CONTINUE CONVERT CORRESPONDING COUNT
CURRENT_SESSION
DATE DEALLOCATE DEC DESCRIBE DESCRIPTOR
DIAGNOSTICS DISCONNECT DOMAIN
ESCAPE EXCEPT EXCEPTION EXEC EXTERNAL
FIRST FOUND
GET GO GOTO
IDENTITY INDICATOR INPUT INTERSECT
LAST LOWER
MAX MIN MODULE
OCTET_LENGTH OPEN OUTPUT OVERLAPS
PREPARE PRESERVE
ROWS
SCHEMA SECTION SESSION SIZE SOME
SQL SQLCODE SQLERROR SQLSTATE SUM SYSTEM_USER
TEMPORARY TRANSLATE TRANSLATION
UNKNOWN UPPER USAGE
VALUE
WHENEVER WRITE
非保留关键字
SQL92 和 SQL3 有一些 非保留关键字,它们在语言里有受约束的含义但是允许被当作标识使用。Postgres 有另外一些关键字允许类似的非限制性使用。具体来说,这些关键字允许当做字段或者表名来用。
下面是 Postgres 非保留关键字,它们既不是 SQL92 也不是 SQL3 的非保留关键字:
ACCESS AFTER AGGREGATE
BACKWARD BEFORE
CACHE COMMENT CREATEDB CREATEUSER CYCLE
DATABASE DELIMITERS
EACH ENCODING EXCLUSIVE
FORCE FORWARD FUNCTION
HANDLER
INCREMENT INDEX INHERITS INSENSITIVE INSTEAD ISNULL
LANCOMPILER LOCATION
MAXVALUE MINVALUE MODE
NOCREATEDB NOCREATEUSER NOTHING NOTIFY NOTNULL
OIDS OPERATOR
PASSWORD PROCEDURAL
RECIPE REINDEX RENAME RETURNS ROW RULE
SEQUENCE SERIAL SHARE START STATEMENT STDIN STDOUT
TEMP TRUSTED
UNLISTEN UNTIL
VALID VERSION
下面是 Postgres 的非保留关键字,但却是 SQL92 或SQL3 的保留关键字:
ABSOLUTE ACTION
CONSTRAINTS
DAY DEFERRABLE DEFERRED
HOUR
IMMEDIATE INITIALLY INSENSITIVE ISOLATION
KEY
LANGUAGE LEVEL
MATCH MINUTE MONTH
NEXT
OF ONLY OPTION
PENDANT PRIOR PRIVILEGES
READ RELATIVE RESTRICT
SCROLL SECOND
TIME TIMESTAMP TIMEZONE_HOUR TIMEZONE_MINUTE TRIGGER
YEAR
ZONE
下面的是 Postgres 的非保留关键字,同时也是 SQL92 或 SQL3的非保留关键字:
COMMITTED SERIALIZABLE TYPE
下面的要么是 SQL92 要么是 SQL3 的非保留关键字,但不是任何类型的 Postgres 的保留字:
ADA
C CATALOG_NAME CHARACTER_SET_CATALOG CHARACTER_SET_NAME
CHARACTER_SET_SCHEMA CLASS_ORIGIN COBOL COLLATION_CATALOG
COLLATION_NAME COLLATION_SCHEMA COLUMN_NAME
COMMAND_FUNCTION CONDITION_NUMBER
CONNECTION_NAME CONSTRAINT_CATALOG CONSTRAINT_NAME
CONSTRAINT_SCHEMA CURSOR_NAME
DATA DATE_TIME_INTERVAL_CODE DATE_TIME_INTERVAL_PRECISION
DYNAMIC_FUNCTION
FORTRAN
LENGTH
MESSAGE_LENGTH MESSAGE_OCTET_LENGTH MORE MUMPS
NAME NULLABLE NUMBER
PAD PASCAL PLI
REPEATABLE RETURNED_LENGTH RETURNED_OCTET_LENGTH
RETURNED_SQLSTATE ROW_COUNT
SCALE SCHEMA_NAME SERVER_NAME SPACE SUBCLASS_ORIGIN
TABLE_NAME
UNCOMMITTED UNNAMED
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
注释
注释 是跟在双减号后面到行末为止的任意排列的字符。例如:
-- 这是一行标准 SQL 注释
我们还支持 C 风格的块注释,例如:
/* multi
line
comment
*/
注释从 "/*" 延伸到第一个 "*/" 的出现。
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
名称
SQL 里面的名称必须以一个字母(a-z)或者下划线(_)开头。名称里随后的字符可以是字母,数字(0-9),或者下划线。系统使用不超过 NAMEDATALEN-1 字符长的名称;更长的名称可以在查询里面写,但是它们会被截断。缺省时,NAMEDATALEN 为 32,因此最大的名称长度是 31(但是在制作系统时,可以通过修改 src/include/postgres_ext.h 里的 NAMEDATALEN 来改变它)。
包含其他字符的名称可以通过用双引号(")包围来形成。例如,如果用双引号包围,一个表或者列的名称可以包含一些不用双引号包围时非法的字符,如空格,与号(&)等。把名称用双引号包围起来同样也令它大小写敏感,而没有用双引号包围的总是折为小写。例如,名称 FOO,foo 和 "foo" 被 Postgres 认为是一样的,但是 "Foo" 是一个不同的名称。
双引号还可以用于保护那些不用双引号包围起来会被认为是一个 SQL 关键字的名称。例如 IN 是一个关键字,而 "IN" 是一个名称。
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
常量
在 Postgres 里使用三种隐含常量:strings(字符串),integers(整数)和floating point numbers(浮点数)。常量也可以被声明为显式的类型,这样可以获得更精确的表示和更有效的后端处理。我们在下面讨论隐含常量;显式常量以后讨论。
字符串常量
SQL 里的 Strings (字符串)是用单引号("'",例如,'这是 一个 字符串')包围的任意 ASCII 字符序列。SQL92 允许通过键入两个相邻的单引号的方法在字符串中嵌入单引号(如:'Dianne''s horse')。在 Postgres 里,单引号可以通过用反斜杠("/")转意的方法来嵌入(如:'Dianne/'s horse')。要在一个字符串常量里包含一个反斜杠,键入两个反斜杠。不可打印的字符也可以用前置反斜杠的方法嵌入字符串(如:'/tab')。
Integer (整数)常量
SQL 里的Integer (整数)常量是一个没有小数点的 ASCII 数字集合。合法的数值范围从-2147483648 到 +2147483647。这个范围会因操作系统和主机(硬件)的不同而异。
注意更大的整数可以用 SQL92 字符串符号或 Postgres 类型符号声明为 int8:
int8 '4000000000' -- string style
'4000000000'::int8 -- Postgres (historical) style
Floating Point (浮点数)常量
Floating point (浮点数)常量包含一个整数部分,一个小数点和下面格式表示的一个小数部分或者科学记数法:
{dig}.{dig} [e [+-] {dig}]
这里 dig 是一或者更多小数位。如果你使用这个选项,你必须在句点和 [+-] 后面包括至少一个 dig。一个没有尾数的指数会被认为有一个为 1 的尾数。在字符串里可能没有嵌入其他额外的字符。
Floating point (浮点数)常量类型是float8。float4 可以用 SQL92 字符串表示法或者 Postgres 类型表示法显式地声明:
float4 '1.23' -- string style
'1.23'::float4 -- Postgres (historical) style
Postgres 用户定义类型的常量
任意 类型的常量可以用下面任何一种表示法输入:
type 'string'
'string'::type
CAST 'string' AS type
字符串里的数值被传递给类型 type 的输入转换过程。结果就是指明类型的常量。如果对于该常量而言,其类型只有一种而没有语意含混的情况,那么显式的类型转换可以省略,这时类型转换是自动强制进行的。
数组常量
数组常量 是任意 Postgres 类型的数组,包括其他数组,字符串常量等。一个数组常量的通用格式如下:
{val1delimval2delim}
这里 delim 是在 pg_type 表里该类型的分隔符。(对于内建类型,这就是逗号字符(","))。一个数组常量的例子是
{{1,2,3},{4,5,6},{7,8,9}}
这个常量是一个二维的,3乘3的,由三个整数的子数组组成的。
独立的数组元素在可能的情况下可以并且也应该放在引号之间,这样与用空白间隔比起来可以避免语意含混的问题。
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
域和列(字段)
域
一个 域 要么是给定表的一个属性,要么是下面之一:
oid
表示一个记录的唯一标识,它是由 Postgres 自动给所有记录附加的。Oid 是不可重用的32位长的数字。
xmin
正在插入的事务的标识。
xmax
正在删除的事务的标识。
cmin
事务内部的命令标识。
cmax
正在删除的事务标识。
关于这些域的更详细信息请参考 Stonebraker, Hanson, Hong, 1987。在系统内部,时间是以 abstime 数据类型的记录表示的。事务和命令标识是32位数。事务是从512开始顺序赋值的。
列
列(字段)是下面形式的构造:
instance{.composite_field}.field `['number`]'
instance 标识一个特定的表,并且可以认为代表该表的实例。一个实例变量要么是一个表的名称,要么是一个用 FROM 子句定义的表的替身或者关键字 NEW 或 CURRENT。NEW 和 CURRENT 只能出现在一个规则的动作部分,而其他实例变量可以在任何 SQL 语句中使用。composite_field 是 Postgres 复合类型之一的一个域,而有效的复合域由表中的字段组成,这些字段正是复合域要计算的。最后,field 是上面提到的表中的一个一般的(基本类型)字段。如果 field 是数组类型,那么可选的 number 指示器指明数组中指定的元素。如果没有指明 number,那么返回所有数组元素。
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
操作符
任何内建的系统或者用户定义操作符都可能在 SQL 里使用。参考 操作符 获取内建的和系统操作符列表。对于用户定义操作符,请询问你的系统管理员或对 pg_operator 表运行查询。圆括号可以在表达式中用于任意操作符的分组。
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
表达式
SQL92 允许用 表达式 在表达式里转换数据。表达式可以包含操作符(参阅 操作符 获取更多信息)和函数(函数 节有更多信息)。
一个表达式是下表中的一种:
( a_expr )
常量
字段
a_expr binary_operator a_expr
a_expr right_unary_operator
left_unary_operator a_expr
参数
函数表达
聚集表达
我们已经讨论了常量和字段。三种操作符表达式分别表示双目(中缀),右目(后缀)和左目(前缀)操作符。下面章节讨论剩下的选项。
参数
一个参数用于表示一个 SQL 函数里面的一个参数。它的典型应用是在 SQL 函数定义语句里。参数的形式如下:
$number
例如,假设一个函数 dept 的定义如下
CREATE FUNCTION dept (name)
RETURNS dept
AS 'select * from
dept where name=$1'
LANGUAGE 'sql';
函数表达式
一个函数表达式是一个合法 SQL 函数的名称,后面跟着它的用圆括号包围的参数列表:
function (a_expr [, a_expr ... ] )
例如,下面的语句计算一个雇员的薪水的平方根:
sqrt(emp.salary)
聚集表达式
一个聚集表达式提供给应用对由一个查询选出来的多个行的聚集功能。一个聚集函数把多个输入缩减为单个输出值,比如对输入的求和或平均。一个聚集表达式的语法是下面形式之一:
aggregate_name (expression)
aggregate_name (ALL expression)
aggregate_name (DISTINCT expression)
aggregate_name ( * )
这里 aggregate_name 是一个预先定义的聚集,并且 expression 是任意自身不包含聚集表达式的表达式。
第一种形式的聚集表达式激活对所有给出的表达式生成的输入行进行聚集计算,生成一个非空值。第二种形式与第一种相同,因为 ALL 是缺省值。第三种形式激活对所有输入行中相异的非空值的聚集计算。最后一种形式激活对每个输入行的单次聚集计算,不管该行是空还是非空值;因为没有声明特定的输入值,这种形式通常只是对 count() 聚集有用。
例如,count(*) 生成所有输入行的总行数;count(f1) 生成 f1 非空的输入行的总行数;count(distinct f1) 生成非空的 f1 的不重复的总行数。
目标列表
一个目标列表是一个或多个插入括号的用逗号分隔的元素列表,每个都必须有下面形式:
a_expr [ AS result_attname ]
这里 result_attname 是要创建的字段名(或者在更新语句里的一个已经存在的字段名。)如果 result_attname 不存在,那么 a_expr 必须只包含一个字段名,这时它被假定为结果域的名称。在Postgres 里,只有 a_expr 是一个字段时才使用缺省命名。
资格条件
一个资格条件包含任何数目的由下面逻辑操作符连结的子句:
NOT
AND
OR
一个子句是一个对一套实例计算生成一个 boolean 的 a_expr。
From 列表
from 列表是一个逗号分隔的 from 表达式 的列表。每个"from 表达式"是下面形式:
[ class_reference ] instance_variable
{, [ class_ref ] instance_variable... }
这里 class_reference 是下面形式
class_name [ * ]
"from 表达式"定义一个或多个实例变量以圈定 class_reference 里指明的表的范围。我们同样还可以用后跟星号("*")限定符的方法要求实例变量的范围包括在继承级中低于指定表的所有表。
--------------------------------------------------------------------------------