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 里指明的表的范圍。我們同樣還可以用后跟星號("*")限定符的方法要求實例變量的范圍包括在繼承級中低于指定表的所有表。
--------------------------------------------------------------------------------