SELECT
名稱
SELECT — 從表或視圖中取出若干行.
SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ]
expression [ AS name ] [, ...]
[ INTO [ TEMPORARY | TEMP ] [ TABLE ] new_table ]
[ FROM table [ alias ] [, ...] ]
[ WHERE condition ]
[ GROUP BY column [, ...] ]
[ HAVING condition [, ...] ]
[ { UNION [ ALL ] | INTERSECT | EXCEPT } select ]
[ ORDER BY column [ ASC | DESC | USING operator ] [, ...] ]
[ FOR UPDATE [ OF class_name [, ...] ] ]
LIMIT { count | ALL } [ { OFFSET | , } start ]
輸入
expression
表的列/欄位名或一個運算式.
name
使用 AS 子句為一個列/欄位或一個運算式聲明另一個名稱.這個名稱主要用於標記輸出資料行。name 不能在 WHERE,GROUP BY或 HAVING 子句中使用。但是它可以在與 ORDER BY 子句裡引用。
TEMPORARY, TEMP
該表是在這次會話中唯一的,並且將在會話結束後自動刪除。
new_table
如果聲明了 INTO TABLE 子句,查詢的結果將儲存在指出名稱的另一個表中.目標表(new_table)將被自動建立並且在此命令執行之前不應該存在。請參考 SELECT INTO 擷取更多資訊.
注意: CREATE TABLE AS 語句也將從選取查詢中建立新表.
table
FORM 子句引用的一個現存的表的名稱.
alias
正在處理的表 table 的別名,用於縮寫或消除一個表內部聯合時的含混.
condition
一個結果為真或假布林運算式.參閱 WHERE 子句擷取更多資訊.
column
表的列/欄位的名稱.
select
一個可以有除 ORDER BY 子句外的所有特性的選擇語句.
輸出
Rows
查詢返回的所有結果集的行.
count
查詢返回的行的記數.
描述
SELECT 將從一個或更多表中返回記錄行。選擇的侯選行是滿足 WHERE 條件的所有行。或者如果省略了 WHERE 語句則選擇表中的所有行.(參閱 WHERE 子句)
DISTINCT 將從選擇出來的結果集中刪除所有的重複的行。ALL (預設)將返回所有侯選行,包括重複的行。
DISTINCT ON 刪除匹配所有運算式的行,只保留每個重複集的第一行。注意這裡每個重複集的"第一行"是不可預料的,除非我們用 ORDER BY 來保證我們希望的行最先出現。例如,
SELECT DISTINCT ON (location) location, time, report
FROM weatherReports
ORDER BY location, time DESC;
檢索出每個地區的最近的天氣預報。但是如果我們沒有使用 ORDER BY 來強制每個地區按時間值降續排列,我們得到的將是每個地區的不可預料的時間的報告。
GROUP BY 子句允許使用者將一個表分成概念上的組. (參閱 GROUP BY 子句。)
HAVING 子句聲明一個分組了的表,該表是從前面聲明的子句的結果集中去除了一些組後產生的.(參閱 HAVING 子句。)
ORDER BY 子句允許使用者根據模式操作符(ASCending 或 DESCending)來表明他/她所希望的行的排序模式(參閱 ORDER BY 子句 )。
UNION 操作符允許結果集是那些涉及到的查詢所返回的行的集合。(參閱 UNION 子句。)
INTERSECT 給出兩個查詢公用的行。(參閱 INTERSECT 子句。)
EXCEPT 給出存在於第一個查詢而不存在於第二個查詢的行。(參閱 EXCEPT 子句。)
FOR UPDATE 子句允許 SELECT 語句對選出的行執行獨佔鎖定。
LIMIT 子句允許給使用者返回一個查詢產生的結果的子集。(參閱 LIMIT 子句。)
你必須有 SELECT 許可權用來從表中讀取數值(參閱 GRANT/REVOKE 語句).
WHERE 子句
可選的 WHERE 條件有如下常見的形式:
WHERE boolean_expr
boolean_expr 可以包含任意個得出布爾值的運算式。通常運算式會是
expr cond_op expr
或
log_op expr
這裡 cond_op 可以是下面之一:=,<,<=,>,>=,<> 或條件操作符象 ALL,ANY,IN,LIKE等,或者使用者定義的操作符,而 log_op 可以為: AND,OR,NOT.比較返回的結果要麼是TRUE 要麼是 FALSET 並且如果運算式的值是 FALSE,所有記錄都將被丟棄.
GROUP BY 子句
GROUP BY 聲明一個分了組的表,該表源於應用使用下面的子句:
GROUP BY column [, ...]
GROUP BY 將把所有在組合了的列上共用同樣的值的行壓縮成一行。如果存在聚集合函式,這些聚集合函式將計算每個組的所有行,並且為每個組計算一個獨立的值(如果沒有 GROUP BY,聚集合函式對選出的所有行計算出一個數值)。存在 GROUP BY 時,除了在聚集合函式裡面,對任何非組合列的引用都是非法的,因為對一個非組合列會有多於一個可能的傳回值。
HAVING 子句
可選的 HAVING 條件有如下形式:
HAVING cond_expr
這裡 cond_expr 與為 WHERE 子句裡聲明的相同.
HAVING 子句聲明一個從前面的子句的結果集中去除了一些不符合 cond_expr 組後分組的表.
在 cond_expr 裡引用的每個列/欄位應該清晰地指明一個組的列/欄位,除非引用在一個聚集合函式裡。
ORDER BY 子句
ORDER BY column [ ASC | DESC ] [, ...]
column 既可以是一個列/欄位名也可以是一個序數。
序數指的是列/欄位按順序(從左至右)的位置.這個特性可以使得對沒有一個合適名稱的列/欄位的排序成為可能.這一點可能永遠沒有用,因為總是可以通過AS 子句給一個要計算的列/欄位賦予一個名稱,例如:
SELECT title, date_prod + 1 AS newlen FROM films ORDER BY newlen;
從 PostgreSQL 版本 6.4 開始,還可以 ORDER BY 任意運算式,包括那些沒有出現在 SELECT 結果清單裡面的域。因此下面的語句現在是合法的:
SELECT name FROM distributors ORDER BY code;
我們可以給ORDER BY 子句裡每個列/欄位加一個關鍵字 DESC (降序)或 ASC(升序).如果不聲明,ASC 是預設.我們還可以聲明一個排序操作符來實現排序。ASC 等效於使用 '<' 而 DESC 等效於使用 '>'。
UNION 子句
table_query UNION [ ALL ] table_query
[ ORDER BY column [ ASC | DESC ] [, ...] ]
這裡 table_query 表明任何沒有 ORDER BY 子句的選擇運算式.
UNION 操作符允許結果集是那些涉及到的查詢所返回的結果的集合。兩個做為 UNION 直接運算元的 SELECT 必鬚生成相同數目的欄位,並且對應的欄位必須有相容的資料類型。
預設地,UNION 的結果不包含任何重複的行,除非聲明了 ALL 子句.
同一 SELECT 語句中的多個 UNION 操作符是從左向右計算的.注意 ALL 關鍵字不一定是全域的,只是應用在當前一對錶的結果上.
INTERSECT 子句
table_query INTERSECT table_query
[ ORDER BY column [ ASC | DESC ] [, ...] ]
這裡 table_query 聲明任何沒有 ORDER BY 子句的選擇運算式。
INTERSECT 給出兩個查詢公用的行。 兩個做為 INTERSECT 直接運算元的 SELECT 的結果必須有相同數目的欄位,並且對應的欄位必須有相容的資料類型。
除非用圓括弧指明順序,同一 SELECT 語句中的多個 INTERSECT 操作符是從左向右計算的。
EXCEPT 子句
table_query EXCEPT table_query
[ ORDER BY column [ ASC | DESC ] [, ...] ]
這裡 table_query 聲明任何沒有 ORDER BY 子句的選擇運算式。
EXCEPT 給出存在於第一個查詢而不存在於第二個查詢的行。(參閱 EXCEPT 子句)。兩個做為 EXCEPT 直接運算元的 SELECT 的結果必須有相同數目的欄位,並且對應的欄位必須有相容的資料類型。
除非用圓括弧指明順序,同一 SELECT 語句中的多個 EXCEPT 操作符是從左向右計算的。
LIMIT 子句
LIMIT { count | ALL } [ { OFFSET | , } start ]
OFFSET start
這裡 count 聲明返回的最大行數,而 start 聲明開始返回行之前忽略的行數。
LIMIT 允許你檢索有查詢其他部分產生的行的某一部分。如果給出了限制計數,那麼返回的行數不會超過哪個限制。如果給出了一個位移量,那麼開始返回行之前會忽略那個數量的行。
在使用 LIMIT 時,一個好習慣是使用一個 ORDER BY 子句把結果行限制成一個唯一的順序。否則你會得到無法預料的查詢返回的子集 --- 你可能想要第十行到第二十行,但以什麼順序?除非你聲明 ORDER BY,否則你不知道什麼順序。
在 Postgres 7.0,查詢最佳化工具在產生查詢規劃時把 LIMIT 考慮進去了,所以你很有可能因給出的 LIMIT 和 OFFSET 值不同而得到不同的規劃(產生不同的行序)。因此用不同的 LIMIT/OFFSET 值選擇不同的查詢結果的子集將不會產生一致的結果,除非你用 ORDER BY 強制產生一個可預計的結果順序。這可不是毛病;這是 SQL 生來的特點,因為除非用了 ORDER BYE 約束順序,SQL 不保證查詢產生的結果有任何特定的順序。
用法
將表 films 和表 distributors 聯合在一起:
SELECT f.title, f.did, d.name, f.date_prod, f.kind
FROM distributors d, films f
WHERE f.did = d.did
title |did|name | date_prod|kind
-------------------------+---+----------------+----------+----------
The Third Man |101|British Lion |1949-12-23|Drama
The African Queen |101|British Lion |1951-08-11|Romantic
Une Femme est une Femme |102|Jean Luc Godard |1961-03-12|Romantic
Vertigo |103|Paramount |1958-11-14|Action
Becket |103|Paramount |1964-02-03|Drama
48 Hrs |103|Paramount |1982-10-22|Action
War and Peace |104|Mosfilm |1967-02-12|Drama
West Side Story |105|United Artists |1961-01-03|Musical
Bananas |105|United Artists |1971-07-13|Comedy
Yojimbo |106|Toho |1961-06-16|Drama
There's a Girl in my Soup|107|Columbia |1970-06-11|Comedy
Taxi Driver |107|Columbia |1975-05-15|Action
Absence of Malice |107|Columbia |1981-11-15|Action
Storia di una donna |108|Westward |1970-08-15|Romantic
The King and I |109|20th Century Fox|1956-08-11|Musical
Das Boot |110|Bavaria Atelier |1981-11-11|Drama
Bed Knobs and Broomsticks|111|Walt Disney | |Musical
統計用 kind 分組的所有電影和組的列/欄位的 len (長度)的和:
SELECT kind, SUM(len) AS total FROM films GROUP BY kind;
kind |total
----------+------
Action | 07:34
Comedy | 02:58
Drama | 14:28
Musical | 06:42
Romantic | 04:38
統計所有電影(films),組的列/欄位 len (長度)的和,用 kind 分組並且顯示小於5小時的組總和:
SELECT kind, SUM(len) AS total
FROM films
GROUP BY kind
HAVING SUM(len) < INTERVAL '5 hour';
kind |total
----------+------
Comedy | 02:58
Romantic | 04:38
下面兩個例子是根據第二列 (name)的內容對單獨的結果排序的經典的方法.
SELECT * FROM distributors ORDER BY name;
SELECT * FROM distributors ORDER BY 2;
did|name
---+----------------
109|20th Century Fox
110|Bavaria Atelier
101|British Lion
107|Columbia
102|Jean Luc Godard
113|Luso films
104|Mosfilm
103|Paramount
106|Toho
105|United Artists
111|Walt Disney
112|Warner Bros.
108|Westward
這個例子示範如何獲得表 distributors 和 actors 的聯合,只將每個表中以字母 W 開頭的取出來.因為只取了不相關的行,所以關鍵字 ALL 被省略了:
-- distributors: actors:
-- did|name id|name
-- ---+------------ --+--------------
-- 108|Westward 1|Woody Allen
-- 111|Walt Disney 2|Warren Beatty
-- 112|Warner Bros. 3|Walter Matthau
-- ... ...
SELECT distributors.name
FROM distributors
WHERE distributors.name LIKE 'W%'
UNION
SELECT actors.name
FROM actors
WHERE actors.name LIKE 'W%'
name
--------------
Walt Disney
Walter Matthau
Warner Bros.
Warren Beatty
Westward
Woody Allen
相容性
擴充
Postgres 允許我們在一個查詢裡省略 FROM 子句。這個特性是從最初的 PostQuel 查詢語言裡保留下來的:
SELECT distributors.* WHERE name = 'Westwood';
did|name
---+----------------
108|Westward
SQL92
SELECT 子句
在SQL92 規範裡,可選的關鍵字 "AS" 是多餘的,可以忽略掉而不對語句產生任何影響.Postgres 分析器在重新命名列/欄位時需要這個關鍵字,因為類型擴充的特性會導致上下文語意不清.
DISTINCT ON 文法不是 SQL92 的標準。LIMIT 和 OFFSET 也不是。
UNION 子句
SQL92 的 UNION 文法允許一個附加的 CORRESPONDING BY 子句:
table_query UNION [ALL]
[CORRESPONDING [BY (column [,...])]]
table_query
CORRESPONDING BY 目前還不被 Postgres 支援.