pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。
SELECT — 从表或视图中检索行
SELECT [ ALL | DISTINCT [ ON (expression[, ...] ) ] ]expression[ ASname] [, ...] [ INTO [ TEMPORARY | TEMP ] [ TABLE ]new_table] [ FROMtable[alias] [, ...] ] [ WHEREcondition] [ GROUP BYcolumn[, ...] ] [ HAVINGcondition[, ...] ] [ { UNION [ ALL ] | INTERSECT | EXCEPT }select] [ ORDER BYcolumn[ ASC | DESC | USINGoperator] [, ...] ] [ FOR UPDATE [ OFclass_name[, ...] ] ] LIMIT {count| ALL } [ { OFFSET | , }start]
expression表的列名或一个表达式。
name用 AS 子句为列或表达式指定另一个名称。此名称主要用于为列提供一个便于显示的标签。它也可以用于在 ORDER BY 和 GROUP BY 子句中引用该列的值。但 name 不能用于 WHERE 或 HAVING 子句;应改写该表达式。
如果指定了 TEMPORARY 或 TEMP,则该表是为此会话唯一创建的,并在会话退出时自动删除。
new_table如果指定了 INTO TABLE 子句,查询结果将存储在一个具有指定名称的新表中。 目标表(new_table)会 自动创建,在此命令执行之前必须不存在。 更多信息请参阅 SELECT INTO。
CREATE TABLE AS 语句同样会从一个 select 查询 创建一个新表。
tableFROM 子句引用的现有表的名称。
alias前面表的替代名称。它用于简洁或消除单个表内连接的歧义。
condition一个结果为真或假的布尔表达式。见 WHERE 子句。
column表的列名。
select一个除 ORDER BY 和 LIMIT 子句外具有所有特性的 select 语句。
由查询说明产生的完整行集合。
count查询返回的行数。
SELECT 将从一个或多个表返回行。选择的候选是满足 WHERE 条件的行;如果省略 WHERE,则所有行都是候选。 (See WHERE 子句.)
DISTINCT 将从结果中消除重复行。 ALL(默认)将返回所有候选行, 包括重复行。
DISTINCT ON 消除在所有指定表达式上匹配的行,只保留每组重复行中的第一行。DISTINCT ON 表达式使用与 ORDER BY 项相同的规则解释;见下文。 注意,除非用 ORDER BY 保证想要的 行出现在最前,否则每个集合的"第一行"是不可预测的。 例如,
SELECT DISTINCT ON (location) location, time, report
FROM weatherReports
ORDER BY location, time DESC;
它取回每个位置的最新天气报告。但如果我们 没有用 ORDER BY 强制每个位置的时间值降序, 就会得到每个位置年龄不可预测的报告。
GROUP BY 子句允许用户把一个表划分为在一个或多个值上匹配的行组。 (See GROUP BY 子句.)
HAVING 子句允许只选择满足指定条件的那些行组。 (See HAVING 子句.)
ORDER BY 子句使返回的行按指定的顺序排序。如果没有给出 ORDER BY,行按系统认为产生成本最低的任何顺序返回。 (See ORDER BY 子句.)
UNION 操作符允许结果是所涉及查询返回的行的集合。 (See UNION 子句.)
INTERSECT 操作符给出两个查询共同的行。 (See INTERSECT 子句.)
EXCEPT 操作符给出第一个查询返回而第二个查询不返回的行。 (See EXCEPT 子句.)
FOR UPDATE 子句允许 SELECT 语句对选中的行执行排他锁定。
LIMIT 子句允许把查询产生的行的一个子集返回给用户。 (See LIMIT 子句.)
你必须对一个表拥有 SELECT 权限才能读取它的值(见 GRANT/REVOKE 语句)。
可选的 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 column [, ...]
GROUP BY 把在分组列上共享相同值的所有选中行压缩为单行。聚合函数(如果使用了的话) 会在组成每个组的所有行上进行计算,为每个组产生一个 单独的值(而没有 GROUP BY 时, 聚合会产生一个在所有被选中的行上计算出的单一值)。当存在 GROUP BY 时, SELECT 输出表达式引用 未分组的列是无效的,除非是在聚合函数内部,因为 对一个未分组的列可能会有多个可能的返回值。
GROUP BY 中的项也可以是输出列(SELECT 表达式)的名称或序号,或者是由输入列值构成的任意表达式。在有歧义时,GROUP BY 名称将被 解释为输入列名而不是输出列名。
可选的 HAVING 条件具有如下一般形式:
HAVING cond_expr
其中 cond_expr 与为 WHERE 子句指定的相同。
HAVING 指定通过消除不满足 cond_expr 的组行而导出的分组表。HAVING 与 WHERE 不同:WHERE 在应用 GROUP BY 之前过滤单独的行,而 HAVING 过滤 GROUP BY 创建的组行。
cond_expr 中引用的每一列都应无歧义地引用一个分组列,除非该引用出现在聚合函数内。
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(降序)或 ASC(升序)。如果未指定,默认为 ASC。或者,可以 指定一个特定的排序操作符名称。ASC 等价于 USING '<' 而 DESC 等价于 USING '>'。
table_queryUNION [ ALL ]table_query[ ORDER BYcolumn[ ASC | DESC ] [, ...] ]
其中 table_query 指定不带 ORDER BY 或 LIMIT 子句的任何 select 表达式。
UNION 操作符允许结果是所涉及查询返回的行的集合。 表示 UNION 的直接操作数的两个 SELECT 必须 产生相同数量的列,并且对应的列必须是 兼容的数据类型。
默认情况下,UNION 的结果不包含任何重复行,除非指定了 ALL 子句。
同一 SELECT 语句中的多个 UNION 操作符从左到右求值。注意 ALL 关键字不是全局性的,只应用于当前这对表结果。
table_queryINTERSECTtable_query[ ORDER BYcolumn[ ASC | DESC ] [, ...] ]
其中 table_query 指定不带 ORDER BY 或 LIMIT 子句的任何 select 表达式。
INTERSECT 操作符给出两个查询共同的行。 表示 INTERSECT 的直接操作数的两个 SELECT 必须 产生相同数量的列,并且对应的列必须是 兼容的数据类型。
同一 SELECT 语句中的多个 INTERSECT 操作符从左到右求值,除非圆括号另有指示。
table_queryEXCEPTtable_query[ ORDER BYcolumn[ ASC | DESC ] [, ...] ]
其中 table_query 指定不带 ORDER BY 或 LIMIT 子句的任何 select 表达式。
EXCEPT 操作符给出第一个查询返回而第二个查询不返回的行。 表示 EXCEPT 的直接操作数的两个 SELECT 必须 产生相同数量的列,并且对应的列必须是 兼容的数据类型。
同一 SELECT 语句中的多个 EXCEPT 操作符从左到右求值,除非圆括号另有指示。
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 BY 约束顺序)这一事实的固有后果。
把表 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)
对所有影片的 len 列求和并按 kind 分组:
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)
对所有影片的 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)
下面两个例子是按照第二列(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 (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 标准中,可选的关键字 "AS" 只是无意义的噪音,可以省略而不影响含义。Postgres 解析器在重命名列时要求这个关键字,因为类型可扩展特性在此上下文中会导致解析歧义。
DISTINCT ON 短语不是 SQL92 的一部分。LIMIT 和 OFFSET 也不是。
在 SQL92 中,ORDER BY 子句只能使用结果列名或编号,而 GROUP BY 子句只能使用输入列名。 Postgres 对这两个子句都做了扩展,允许也使用另一种选择 (但在有歧义时采用标准的解释)。 Postgres 还允许两个子句指定任意表达式。注意,表达式中出现的名称 将总是被当作输入列名,而不是结果列名。
SQL92 的 UNION 语法允许一个附加的 CORRESPONDING BY 子句:
table_queryUNION [ALL] [CORRESPONDING [BY (column[,...])]]table_query
Postgres 不支持 CORRESPONDING BY 子句。
译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。