↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
测试与开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1 / 7.0 / 6.5 / 6.4
历史版本PostgreSQL 6.5 已于 2004 年 6 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本。

SELECT

SELECT — 从表或视图中检索行

大纲

SELECT [ALL|DISTINCT [ON column] ]
    expression [ AS
   name ] [, ...]
    [ INTO [TEMP] [TABLE] new_table ]
    [ FROM table
   [alias ] [, ...] ]
    [ WHERE condition ]
    [ GROUP BY column [, ...] ]
    [ HAVING condition [, ...] ]
    [ { UNION [ALL] | INTERSECT | EXCEPT } select ]
    [ ORDER BY column [ ASC | DESC ] [, ...] ]
    [ FOR UPDATE [OF class_name...]]
    [ LIMIT count [OFFSET|, count]]
  

输入

expression

表的列名或一个表达式。

name

用 AS 子句为列或表达式指定另一个名称。 name 不能用于 WHERE 条件中。但它可以在相关的 ORDER BY 或 GROUP BY 子句中引用。

TEMP

该表是为此会话唯一创建的,并在会话退出时自动删除。

new_table

如果指定了 INTO TABLE 子句,查询结果将存储在另一个具有指定名称的表中。 目标表(new_table)会 自动创建,在此命令执行之前应当不存在。 更多信息请参阅 SELECT INTO。

注意

CREATE TABLE AS 语句也可以 从一个选择查询创建新表。

table

FROM 子句引用的现有表的名称。

alias

前面表的替代名称。它用于简洁或消除单个表内连接的歧义。

condition

一个结果为真或假的布尔表达式。见 WHERE 子句。

column

表的列名。

select

一个除 ORDER BY 子句外具有所有特性的 select 语句。

输出

Rows

由查询说明产生的完整行集合。

→ count

查询返回的行数。

描述

SELECT 将从一个或多个表返回行。 选择的候选是满足 WHERE 条件的行; 如果省略 WHERE,所有行都是候选。

DISTINCT 将从选择中消除所有重复行。 DISTINCT ON column 将消除指定列中的所有重复项;这等价于使用 GROUP BY column。ALL 将返回所有候选行, 包括重复行。

GROUP BY 子句允许用户在概念上把一个表划分为若干组。 (见 GROUP BY 子句)。

HAVING 子句指定通过从先前指定子句的结果中消除某些组而导出的分组表。 (见 HAVING 子句)。

ORDER BY 子句允许用户指定希望行按升序或降序模式操作符排序。 (见 ORDER BY 子句)

UNION 子句允许结果是所涉及查询返回的行的集合。 (见 UNION 子句)。

INTERSECT 给出两个查询共同的行。 (见 INTERSECT 子句)。

EXCEPT 给出上层查询中有而下层查询中没有的行。 (见 EXCEPT 子句)。

FOR UPDATE 子句允许 SELECT 语句对选中的行执行排他锁定。 (见 EXCEPT 子句)。

LIMIT...OFFSET 子句允许控制查询返回哪些行。

你必须对一个表拥有 SELECT 权限才能读取它的值(见 GRANT/REVOKE 语句)。

WHERE 子句

可选的 WHERE 条件具有如下一般形式:

WHERE expr ETER">ce"PARreplaceable> [ log_op ... ]
    

其中 cond_op 可以是 =、<、<=、>、>= 或 <> 之一, 或像 ALL、ANY、IN、LIKE 等这样的条件操作符,或 本地定义的操作符, 而 log_op 可以是 AND、OR、NOT 之一。 比较返回 TRUE 或 FALSE,如果 表达式求值为 FALSE, 所有实例都会被丢弃。

GROUP BY 子句

GROUP BY 指定通过应用此子句导出的分组表:

GROUP BY column [, ...]
    

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。

UNION 子句

table_query UNION [ ALL ]
table_query
     [ ORDER BY column [ ASC | DESC ] [, ...] ]
    

其中 table_query 指定不带 ORDER BY 子句的任何 select 表达式。

UNION 子句允许结果是所涉及查询返回的行的集合。(见 UNION 子句。) 表示 UNION 的直接操作数的两个表必须 具有相同数量的列,并且对应的列必须是 兼容的数据类型。

默认情况下,UNION 的结果不包含任何重复行,除非指定了 ALL 子句。

同一 SELECT 语句中的多个 UNION 操作符从左到右求值。注意 ALL 关键字不是全局性的,只应用于当前这对表结果。

INTERSECT 子句

table_query INTERSECT
table_query
     [ ORDER BY column [ ASC | DESC ] [, ...] ]
    

其中 table_query 指定不带 ORDER BY 子句的任何 select 表达式。

INTERSECT 子句允许结果是所涉及查询共同的所有行。(见 INTERSECT 子句。) 表示 INTERSECT 的直接操作数的两个表必须 具有相同数量的列,并且对应的列必须是 兼容的数据类型。

同一 SELECT 语句中的多个 INTERSECT 操作符从左到右求值。

EXCEPT 子句

table_query EXCEPT
     table_query
     [ ORDER BY column [ ASC | DESC ] [, ...] ]
    

其中 table_query 指定不带 ORDER BY 子句的任何 select 表达式。

EXCEPT 子句允许结果是上层查询中有而下层查询中没有的行。(见 EXCEPT 子句。) 表示 EXCEPT 的直接操作数的两个表必须 具有相同数量的列,并且对应的列必须是 兼容的数据类型。

同一 SELECT 语句中的多个 EXCEPT 操作符从左到右求值。

用法

把表 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
  

兼容性

扩展

Postgres 允许在查询中省略 FROM 子句。此特性是从最初的 PostQuel 查询语言保留下来的:

SELECT distributors.* WHERE name = 'Westwood';

    did|name
    ---+----------------
    108|Westward
  

SQL92

SELECT 子句

在 SQL92 标准中,可选的关键字 "AS" 只是无意义的噪音,可以省略而不影响含义。Postgres 解析器在重命名列时要求这个关键字,因为类型可扩展特性在此上下文中会导致解析歧义。

在 SQL92 标准中,"AS" 子句中指定的新列名可以在 GROUP BY 和 HAVING 子句中引用。目前在 Postgres 中不允许这样做。

DISTINCT ON 短语不是 SQL92 的一部分。

UNION 子句

SQL92 的 UNION 语法允许一个附加的 CORRESPONDING BY 子句:

 
table_query UNION [ALL]
    [CORRESPONDING [BY (column [,...])]]
    table_query
     

Postgres 不支持 CORRESPONDING BY 子句。

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。