PostgreSQL7.0手冊-用戶手冊-19. SQL命令-SELECT
2019-09-08 23:33:39
供稿:網友
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,該表是在這次會話中唯一的,并且將在會話結束后自動刪除?!?
new_table
如果聲明了 INTO TABLE 子句,查詢的結果將存儲在指出名稱的另一個表中.目標表(new_table)將被自動創建并且在此命令執行之前不應該存在。請參考 SELECT INTO 獲取更多信息.
注意: CREATE TABLE AS 語句也將從選擇查詢中創建新表.
table
FORM 子句引用的一個現存的表的名稱.
alias
正在處理的表 table 的別名,用于縮寫或消除一個表內部聯合時的含混.
condition
一個結果為真或假布爾表達式.參閱 WHERE 子句獲取更多信息.
column
表的列/字段的名稱.
select
除了 ORDER BY 和 LIMIT 子句外的所有特性的選擇語句.
輸出
Rows
查詢返回的所有結果集的行.
count
查詢返回的行的記數.
描述SELECT 將從一個或更多表中返回記錄行。選擇的侯選行是滿足 WHERE 條件的所有行?;蛘呷绻÷粤恕HERE 語句則選擇表中的所有行.(參閱WHERE Clause.)
DISTINCT 將從選擇出來的結果集中刪除所有的重復的行。ALL?。ㄈ笔。⒎祷厮泻钸x行,包括重復的行?!?
DISTINCT ON 刪除匹配所有表達式的行,只保留每個重復集的第一行。注意這里每個重復集的"第一行"是不可預料的,除非我們用 ORDER BY 來保證我們希望的行最先出現。例如,
SELECT DISTINCT ON (location) location, time, report
FROM weatherReports
ORDER BY location, time DESC;
檢索出每個地區的最近的天氣預報。但是如果我們沒有使用 ORDER BY 來強制每個地區按時間值降續排列,我們得到的將是每個地區的不可預料的時間的報告?!?
檢索出每個地區的最近的天氣預報。但是如果我們沒有使用 ORDER BY 來強制每個地區按時間值降續排列,我們得到的將是每個地區的不可預料的時間的報告。( GROUP BY 子句.)
HAVING 允許只選擇那些滿足聲明條件的行組(參閱 HAVING 子句.)
ORDER BY 導致返回的行按照聲明的順序排列.如果沒有給出 ORDER BY,輸出的行的順序將以系統認為開銷最小的順序產生.(參閱 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.SELECT 將忽略所有 WHERE 條件不為 TRUE 的行.
GROUP BY 子句
GROUP BY 聲明一個分了組的表,該表源于應用使用下面的子句:
GROUP BY column [, ...]
GROUP BY 將把所有在組合了的列上共享同樣的值的行壓縮成一行。如果存在聚集函數,這些聚集函數將計算每個組的所有行,并且為每個組計算一個獨立的值(如果沒有 GROUP BY,聚集函數對選出的所有行計算出一個數值)。存在 GROUP BY 時,除了在聚集函數里面,SELECT 輸出表達式對任何非組合列的引用都是非法的,因為對一個非組合列會有多于一個可能的返回值。
一個在 GROUP BY 里面的條目還可以是輸出列的名稱或者序號(SELECT 表達式),或者是一個從輸入列的數值形成的任意表達式.當存在語義模糊時,一個 GROUP BY 名稱將被解釋成一個輸入列/字段名稱而不是一個輸出列/字段名稱.
HAVING 子句
可選的 HAVING 條件有如下形式:
HAVING cond_expr
這里 cond_expr 與為 WHERE 子句里聲明的相同.
HAVING 子句聲明一個從前面的子句的結果集中去除了一些不符合 cond_expr 組后分組的表.HAVING 與 WHERE 不同:WHERE 在應用 GROUP BY 之前過濾出單獨的行,而 HAVING 過濾由 GROUP BY 創建的行.
在 cond_expr 里引用的每個列/字段應該清晰地指明一個組的列/字段,除非引用在一個聚集函數里?!?
ORDER BY 子句
ORDER BY column [ ASC | DESC ] [, ...]
column 既可以是一個列/字段名也可以是一個序數?!?
序數指的是列/字段按順序(從左到右)的位置.這個特性可以使得對沒有一個合適名稱的列/字段的排序成為可能.這一點可能永遠沒有用,因為總是可以通過AS 子句給一個要計算的列/字段賦予一個名稱,例如:
SELECT title, date_prod + 1 AS newlen FROM films ORDER BY newlen;
還可以 ORDER BY 任意表達式(一個對 SQL92 的擴展),包括那些沒有出現在 SELECT 結果列表里面的域。因此下面的語句現在是合法的:
SELECT name FROM distributors ORDER BY code;
請注意如果一個 ORDER BY 條目是一個匹配結果列和輸入列的簡單名稱,ORDER BY 將把它解釋成結果列名稱.這和 GROUP BY 在同樣情況下做的選擇正相反.這樣的不一致是由 SQL92 標準強制的.
我們可以給ORDER BY 子句里每個列/字段加一個關鍵字 DESC?。ń敌颍┗颉SC(升序).如果不聲明,ASC 是缺省.我們還可以聲明一個排序操作符來實現排序。ASC 等效于使用 '<' 而 DESC 等效于使用 '>'。
UNION 子句
table_query UNION [ ALL ] table_query
[ ORDER BY column [ ASC | DESC ] [, ...] ]
這里 table_query 表明任何沒有 ORDER BY 或者 LIMIT 子句的選擇表達式.
UNION 操作符允許結果集是那些涉及到的查詢所返回的結果的集合。兩個做為 UNION 直接操作數的 SELECT 必須生成相同數目的字段,并且對應的字段必須有兼容的數據類型。
缺省地,UNION 的結果不包含任何重復的行,除非聲明了 ALL 子句.
同一 SELECT 語句中的多個 UNION 操作符是從左向右計算的.注意 ALL 關鍵字不一定是全局的,只是應用在當前一對表的結果上.
INTERSECT 子句
table_query INTERSECT table_query
[ ORDER BY column [ ASC | DESC ] [, ...] ]
這里 table_query 聲明任何沒有 ORDER BY 或者 LIMIT 子句的選擇表達式?!?
INTERSECT 給出兩個查詢公共的行。 兩個做為 INTERSECT 直接操作數的 SELECT 的結果必須有相同數目的字段,并且對應的字段必須有兼容的數據類型。
除非用圓括號指明順序,同一 SELECT 語句中的多個 INTERSECT 操作符是從左向右計算的。
EXCEPT 子句
table_query EXCEPT table_query
[ ORDER BY column [ ASC | DESC ] [, ...] ]
這里 table_query 聲明任何沒有 ORDER BY 或者 LIMIT 子句的選擇表達式?!?
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
(17 rows)
統計用 kind 分組的所有電影和組的列/字段的 len?。ㄩL度)的和:
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)
統計所有電影(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)
下面兩個例子是根據第二列?。╪ame)的內容對單獨的結果排序的經典的方法.
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 的聯合,只將每個表中以字母 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 也不是?!?
在 SQL92 里,一個 ORDER BY 子句只可以使用在結果列名稱或者序號上,而 GROUP BY 子句只能用于輸入列/字段上.Postgres 把這兩個子句都擴展為允許另一種選擇(但是如果出現沖突則使用標準的解釋).Postgres 還允許兩個子句聲明任意的表達式.請注意,在表達式里出現的名稱將總是被當做輸入列/字段的名稱,而不是結果列/字段名稱.
UNION 子句
SQL92 的 UNION 語法允許一個附加的 CORRESPONDING BY 子句:
table_query UNION [ALL]
[CORRESPONDING [BY (column [,...])]]
table_query
CORRESPONDING BY 目前還不被 Postgres 支持.