pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。
SELECT — 从表或视图中检索行
SELECT [ALL|DISTINCT [ONcolumn] ]expression[ ASname] [, ...] [ INTO [TABLE]new_table] [ FROMtable[alias] [, ...] ] [ WHEREcondition] [ GROUP BYcolumn[, ...] ] [ HAVINGcondition[, ...] ] [ UNION [ALL]select] [ ORDER BYcolumn[ ASC | DESC ] [, ...] ]
expression表的列名或一个表达式。
name用 AS 子句为列或表达式指定另一个名称。 name 不能用于 WHERE 条件中。但它可以在相关的 ORDER BY 或 GROUP BY 子句中引用。
new_table如果指定了 INTO TABLE 子句,查询结果将存储在另一个具有指定名称的表中。 如果 new_table 不存在,将自动创建它。更多信息参见 SELECT INTO。
CREATE TABLE AS 语句也会从一个 select 查询创建一个新表。
tableFROM 子句引用的现有表的名称。
alias前面表的替代名称。它用于简洁或消除单个表内连接的歧义。
condition一个结果为真或假的布尔表达式。见 WHERE 子句。
column表的列名。
select一个除 ORDER BY 子句外具有所有特性的 select 语句。
由查询说明产生的完整行集合。
count查询返回的行数。
SELECT 将取回满足 WHERE 条件的所有行, 如果省略 WHERE,则取回一个表的所有行。
GROUP BY 子句允许用户在概念上把一个表划分为若干组。 (见 GROUP BY 子句)。
HAVING 子句指定通过从先前指定子句的结果中消除某些组而导出的分组表。 (见 HAVING 子句)。
ORDER BY 子句允许用户指定希望行按升序或降序模式操作符排序。 (见 ORDER BY 子句)
UNION 子句指定一个由笛卡尔积并连接导出的表。 (见 UNION 子句)。
你必须对一个表拥有 SELECT 权限才能读取它的值(见 GRANT/REVOKE 语句)。
可选的 WHERE 条件具有如下一般形式:
WHEREexprcond_opexpr[log_op... ]
其中 cond_op 可以是 =、<、<=、>、>=、<> 之一,或 ALL、ANY、IN、LIKE 等条件操作符,而 log_op 可以是 AND、OR、NOT 之一。 比较返回 TRUE 或 FALSE,如果表达式求值为 FALSE 则所有实例都被丢弃。
GROUP BY 指定通过应用此子句导出的分组表:
GROUP BY column [, ...]
可选的 HAVING 条件具有如下一般形式:
HAVING cond_expr
其中 cond_expr 与为 WHERE 子句指定的相同。
HAVING 指定通过从先前指定子句的结果中消除不满足 cond_expr 的组而导出的分组表。
cond_expr 中引用的每一列都应无歧义地引用一个分组列。
ORDER BY column [ ASC | DESC ] [, ...]
column 既可以是列名,也可以是序号。
序号指列的(从左到右的)位置。此特性使得可以基于没有合适名称的列定义排序。 这永远不是绝对必要的,因为总是可以 用 AS 子句为计算列 赋予一个名称,例如:
SELECT title, date_prod + 1 AS newlen FROM films ORDER BY newlen;
ORDER BY 中的列必须出现在 SELECT 子句中。因此下面的语句是非法的:
SELECT name FROM distributors ORDER BY code;
还可以在 ORDER BY 子句中的每个列名后面添加关键字 DESC(降序)或 ASC(升序)。如果未指定,默认为 ASC。
table_queryUNION [ ALL ]table_query[ ORDER BYcolumn[ ASC | DESC ] [, ...] ]
其中 table_query 指定不带 ORDER BY 子句的任何 select 表达式。
UNION 操作符指定一个由笛卡尔积导出的表。表示 UNION 的直接操作数的两个表必须具有相同数量的列,并且对应的列必须是兼容的数据类型。
默认情况下,UNION 的结果不包含任何重复行,除非指定了 ALL 子句。
同一 SELECT 语句中的多个 UNION 操作符从左到右求值。注意 ALL 关键字不是全局性的,只应用于当前这对表结果。
把表 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
对所有影片的 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
对所有影片的 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
在 SQL92 标准中,可选的关键字 "AS" 只是无意义的噪音,可以省略而不影响含义。Postgres 解析器在重命名列时要求这个关键字,因为类型可扩展特性在此上下文中会导致解析歧义。
在 SQL92 标准中,"AS" 子句中指定的新列名可以在 GROUP BY 和 HAVING 子句中引用。目前在 Postgres 中不允许这样做。
SQL92 的 UNION 语法允许一个附加的 CORRESPONDING BY 子句:
table_queryUNION [ALL] [CORRESPONDING [BY (column[,...])]]table_query
Postgres 不支持 CORRESPONDING BY 子句。
译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。