PostgreSQL7.0手冊-用戶手冊-19. SQL命令-SELECT
2019-09-08 23:33:39
供稿:網(wǎng)友
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 子句為一個列/字段或一個表達式聲明另一個名稱.這個名稱主要用于標記輸出列用于顯示。它可以在 ORDER BY 和 GROUP BY 子句里代表列/字段的值.但是 name 不能用于 WHERE 或 HAVING 子句;用表達式代替.
TEMPORARY, TEMP
如果聲明了 TEMPORARY 或 TEMP,該表是在這次會話中唯一的,并且將在會話結(jié)束后自動刪除。
new_table
如果聲明了 INTO TABLE 子句,查詢的結(jié)果將存儲在指出名稱的另一個表中.目標表(new_table)將被自動創(chuàng)建并且在此命令執(zhí)行之前不應該存在。請參考 SELECT INTO 獲取更多信息.
注意: CREATE TABLE AS 語句也將從選擇查詢中創(chuàng)建新表.
table
FORM 子句引用的一個現(xiàn)存的表的名稱.
alias
正在處理的表 table 的別名,用于縮寫或消除一個表內(nèi)部聯(lián)合時的含混.
condition
一個結(jié)果為真或假布爾表達式.參閱 WHERE 子句獲取更多信息.
column
表的列/字段的名稱.
select
除了 ORDER BY 和 LIMIT 子句外的所有特性的選擇語句.
輸出
Rows
查詢返回的所有結(jié)果集的行.
count
查詢返回的行的記數(shù).
描述SELECT 將從一個或更多表中返回記錄行。選擇的侯選行是滿足 WHERE 條件的所有行。或者如果省略了 WHERE 語句則選擇表中的所有行.(參閱WHERE Clause.)
DISTINCT 將從選擇出來的結(jié)果集中刪除所有的重復的行。ALL (缺省)將返回所有侯選行,包括重復的行。
DISTINCT ON 刪除匹配所有表達式的行,只保留每個重復集的第一行。注意這里每個重復集的"第一行"是不可預料的,除非我們用 ORDER BY 來保證我們希望的行最先出現(xiàn)。例如,
SELECT DISTINCT ON (location) location, time, report
FROM weatherReports
ORDER BY location, time DESC;
檢索出每個地區(qū)的最近的天氣預報。但是如果我們沒有使用 ORDER BY 來強制每個地區(qū)按時間值降續(xù)排列,我們得到的將是每個地區(qū)的不可預料的時間的報告。
檢索出每個地區(qū)的最近的天氣預報。但是如果我們沒有使用 ORDER BY 來強制每個地區(qū)按時間值降續(xù)排列,我們得到的將是每個地區(qū)的不可預料的時間的報告。( GROUP BY 子句.)
HAVING 允許只選擇那些滿足聲明條件的行組(參閱 HAVING 子句.)
ORDER BY 導致返回的行按照聲明的順序排列.如果沒有給出 ORDER BY,輸出的行的順序?qū)⒁韵到y(tǒng)認為開銷最小的順序產(chǎn)生.(參閱 ORDER BY 子句.)
UNION 操作符允許結(jié)果集是那些涉及到的查詢所返回的行的集合。(參閱 UNION 子句。)
INTERSECT 給出兩個查詢公共的行。(參閱 INTERSECT 子句。)
EXCEPT 給出存在于第一個查詢而不存在于第二個查詢的行。(參閱 EXCEPT 子句。)
FOR UPDATE 子句允許 SELECT 語句對選出的行執(zhí)行排他鎖。
LIMIT 子句允許給用戶返回一個查詢生成的結(jié)果的子集。(參閱 LIMIT 子句。)
你必須有 SELECT 權(quán)限用來從表中讀取數(shù)值 (參閱 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.SELECT 將忽略所有 WHERE 條件不為 TRUE 的行.
GROUP BY 子句
GROUP BY 聲明一個分了組的表,該表源于應用使用下面的子句:
GROUP BY column [, ...]
GROUP BY 將把所有在組合了的列上共享同樣的值的行壓縮成一行。如果存在聚集函數(shù),這些聚集函數(shù)將計算每個組的所有行,并且為每個組計算一個獨立的值(如果沒有 GROUP BY,聚集函數(shù)對選出的所有行計算出一個數(shù)值)。存在 GROUP BY 時,除了在聚集函數(shù)里面,SELECT 輸出表達式對任何非組合列的引用都是非法的,因為對一個非組合列會有多于一個可能的返回值。
一個在 GROUP BY 里面的條目還可以是輸出列的名稱或者序號(SELECT 表達式),或者是一個從輸入列的數(shù)值形成的任意表達式.當存在語義模糊時,一個 GROUP BY 名稱將被解釋成一個輸入列/字段名稱而不是一個輸出列/字段名稱.
HAVING 子句
可選的 HAVING 條件有如下形式:
HAVING cond_expr
這里 cond_expr 與為 WHERE 子句里聲明的相同.
HAVING 子句聲明一個從前面的子句的結(jié)果集中去除了一些不符合 cond_expr 組后分組的表.HAVING 與 WHERE 不同:WHERE 在應用 GROUP BY 之前過濾出單獨的行,而 HAVING 過濾由 GROUP BY 創(chuàng)建的行.
在 cond_expr 里引用的每個列/字段應該清晰地指明一個組的列/字段,除非引用在一個聚集函數(shù)里。
ORDER BY 子句
ORDER BY column [ ASC | DESC ] [, ...]
column 既可以是一個列/字段名也可以是一個序數(shù)。
序數(shù)指的是列/字段按順序(從左到右)的位置.這個特性可以使得對沒有一個合適名稱的列/字段的排序成為可能.這一點可能永遠沒有用,因為總是可以通過AS 子句給一個要計算的列/字段賦予一個名稱,例如:
SELECT title, date_prod + 1 AS newlen FROM films ORDER BY newlen;
還可以 ORDER BY 任意表達式(一個對 SQL92 的擴展),包括那些沒有出現(xiàn)在 SELECT 結(jié)果列表里面的域。因此下面的語句現(xiàn)在是合法的:
SELECT name FROM distributors ORDER BY code;
請注意如果一個 ORDER BY 條目是一個匹配結(jié)果列和輸入列的簡單名稱,ORDER BY 將把它解釋成結(jié)果列名稱.這和 GROUP BY 在同樣情況下做的選擇正相反.這樣的不一致是由 SQL92 標準強制的.
我們可以給ORDER BY 子句里每個列/字段加一個關(guān)鍵字 DESC (降序)或 ASC(升序).如果不聲明,ASC 是缺省.我們還可以聲明一個排序操作符來實現(xiàn)排序。ASC 等效于使用 '<' 而 DESC 等效于使用 '>'。
UNION 子句
table_query UNION [ ALL ] table_query
[ ORDER BY column [ ASC | DESC ] [, ...] ]
這里 table_query 表明任何沒有 ORDER BY 或者 LIMIT 子句的選擇表達式.
UNION 操作符允許結(jié)果集是那些涉及到的查詢所返回的結(jié)果的集合。兩個做為 UNION 直接操作數(shù)的 SELECT 必須生成相同數(shù)目的字段,并且對應的字段必須有兼容的數(shù)據(jù)類型。
缺省地,UNION 的結(jié)果不包含任何重復的行,除非聲明了 ALL 子句.
同一 SELECT 語句中的多個 UNION 操作符是從左向右計算的.注意 ALL 關(guān)鍵字不一定是全局的,只是應用在當前一對表的結(jié)果上.
INTERSECT 子句
table_query INTERSECT table_query
[ ORDER BY column [ ASC | DESC ] [, ...] ]
這里 table_query 聲明任何沒有 ORDER BY 或者 LIMIT 子句的選擇表達式。
INTERSECT 給出兩個查詢公共的行。 兩個做為 INTERSECT 直接操作數(shù)的 SELECT 的結(jié)果必須有相同數(shù)目的字段,并且對應的字段必須有兼容的數(shù)據(jù)類型。
除非用圓括號指明順序,同一 SELECT 語句中的多個 INTERSECT 操作符是從左向右計算的。
EXCEPT 子句
table_query EXCEPT table_query
[ ORDER BY column [ ASC | DESC ] [, ...] ]
這里 table_query 聲明任何沒有 ORDER BY 或者 LIMIT 子句的選擇表達式。
EXCEPT 給出存在于第一個查詢而不存在于第二個查詢的行。(參閱 EXCEPT 子句)。兩個做為 EXCEPT 直接操作數(shù)的 SELECT 的結(jié)果必須有相同數(shù)目的字段,并且對應的字段必須有兼容的數(shù)據(jù)類型。
除非用圓括號指明順序,同一 SELECT 語句中的多個 EXCEPT 操作符是從左向右計算的。
LIMIT 子句
LIMIT { count | ALL } [ { OFFSET | , } start ]
OFFSET start
這里 count 聲明返回的最大行數(shù),而 start 聲明開始返回行之前忽略的行數(shù)。
LIMIT 允許你檢索有查詢其他部分生成的行的某一部分。如果給出了限制計數(shù),那么返回的行數(shù)不會超過哪個限制。如果給出了一個偏移量,那么開始返回行之前會忽略那個數(shù)量的行。
在使用 LIMIT 時,一個好習慣是使用一個 ORDER BY 子句把結(jié)果行限制成一個唯一的順序。否則你會得到無法預料的查詢返回的子集 --- 你可能想要第十行到第二十行,但以什么順序?除非你聲明 ORDER BY,否則你不知道什么順序。
在 Postgres 7.0,查詢優(yōu)化器在生成查詢規(guī)劃時把 LIMIT 考慮進去了,所以你很有可能因給出的 LIMIT 和 OFFSET 值不同而得到不同的規(guī)劃(生成不同的行序)。因此用不同的 LIMIT/OFFSET 值選擇不同的查詢結(jié)果的子集將不會產(chǎn)生一致的結(jié)果,除非你用 ORDER BY 強制生成一個可預計的結(jié)果順序。這可不是毛病;這是 SQL 生來的特點,因為除非用了 ORDER BYE 約束順序,SQL 不保證查詢生成的結(jié)果有任何特定的順序。
用法
將表 films 和表 distributors 聯(lián)合在一起:
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
(17 rows)
統(tǒng)計用 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
(5 rows)
統(tǒng)計所有電影(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
(2 rows)
下面兩個例子是根據(jù)第二列 (name)的內(nèi)容對單獨的結(jié)果排序的經(jīng)典的方法.
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
(13 rows)
這個例子演示如何獲得表 distributors 和 actors 的聯(lián)合,只將每個表中以字母 W 開頭的取出來.因為只取了不相關(guān)的行,所以關(guān)鍵字 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 規(guī)范里,可選的關(guān)鍵字 "AS" 是多余的,可以忽略掉而不對語句產(chǎn)生任何影響.Postgres 分析器在重命名列/字段時需要這個關(guān)鍵字,因為類型擴展的特性會導致上下文語意不清.
DISTINCT ON 語法不是 SQL92 的標準。LIMIT 和 OFFSET 也不是。
在 SQL92 里,一個 ORDER BY 子句只可以使用在結(jié)果列名稱或者序號上,而 GROUP BY 子句只能用于輸入列/字段上.Postgres 把這兩個子句都擴展為允許另一種選擇(但是如果出現(xiàn)沖突則使用標準的解釋).Postgres 還允許兩個子句聲明任意的表達式.請注意,在表達式里出現(xiàn)的名稱將總是被當做輸入列/字段的名稱,而不是結(jié)果列/字段名稱.
UNION 子句
SQL92 的 UNION 語法允許一個附加的 CORRESPONDING BY 子句:
table_query UNION [ALL]
[CORRESPONDING [BY (column [,...])]]
table_query
CORRESPONDING BY 目前還不被 Postgres 支持.