2024年9月26日: PostgreSQL 17 发布!
支持的版本:当前 (17) / 16 / 15 / 14 / 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.3. 选择列表 #

如上一节所示,SELECT 命令中的表表达式通过可能组合表、视图、消除行、分组等构建一个中间虚拟表。此表最终传递给选择列表进行处理。选择列表确定实际上输出中间表的哪些

7.3.1. 选择列表项 #

最简单的选择列表是*,它会发出表表达式生成的全部列。否则,选择列表是由逗号分隔的值表达式列表(如第 4.2 节中所定义)。例如,它可以是列名列表

SELECT a, b, c FROM ...

列名abc要么是FROM子句中引用的表的列的实际名称,要么是如第 7.2.1.2 节中所解释的那样赋予它们的别名。选择列表中可用的命名空间与WHERE子句中相同,除非使用分组,在这种情况下,它与HAVING子句中相同。

如果多个表具有相同名称的列,则还必须给出表名,如下所示:

SELECT tbl1.a, tbl2.a, tbl1.b FROM ...

在处理多个表时,请求特定表的全部列也很有用

SELECT tbl1.*, tbl2.a FROM ...

有关table_name.*表示法的更多信息,请参阅第 8.16.5 节

如果在选择列表中使用任意值表达式,则它会在概念上向返回的表添加一个新的虚拟列。对于每一行结果,都会评估一次值表达式,并将行的值替换为任何列引用。但是,选择列表中的表达式不必引用FROM子句的表表达式的任何列;例如,它们可以是常数算术表达式。

7.3.2. 列标签 #

选择列表中的条目可以为后续处理(例如,在ORDER BY子句中使用或由客户端应用程序显示)分配名称。例如

SELECT a AS value, b + c AS sum FROM ...

如果没有使用AS指定输出列名,则系统会分配一个默认列名。对于简单的列引用,它是引用的列的名称。对于函数调用,它是函数的名称。对于复杂表达式,系统将生成一个通用名称。

AS关键字通常是可选的,但在某些情况下,如果所需的列名与PostgreSQL关键字匹配,则必须编写AS或将列名用双引号括起来以避免歧义。(附录 C显示哪些关键字需要使用AS作为列标签。)例如,FROM就是一个这样的关键字,因此此方法无效

SELECT a from, b + c AS sum FROM ...

但以下任一方法都可以

SELECT a AS from, b + c AS sum FROM ...
SELECT a "from", b + c AS sum FROM ...

为了最大程度地防止未来可能添加的关键字带来的问题,建议始终编写AS或将输出列名用双引号括起来。

注意

此处输出列的命名方式不同于在FROM子句中执行的命名方式(请参阅第 7.2.1.2 节)。可以对同一列重命名两次,但选择列表中分配的名称是将要传递的名称。

7.3.3. DISTINCT #

处理选择列表后,结果表可以选择性地进行重复行的消除。DISTINCT关键字直接写在SELECT之后以指定此操作

SELECT DISTINCT select_list ...

(可以使用关键字ALL代替DISTINCT来指定保留所有行的默认行为。)

显然,如果两行至少在一个列值上不同,则它们被视为不同的。空值在此比较中被视为相等。

或者,可以使用任意表达式来确定哪些行被视为不同的

SELECT DISTINCT ON (expression [, expression ...]) select_list ...

此处expression是为所有行计算的任意值表达式。对于所有表达式都相等的行集,它们被视为重复项,并且仅保留该集中第一行在输出中。请注意,除非查询已针对足够的列进行排序以保证到达DISTINCT过滤器的行的唯一排序,否则该集合的第一行是不可预测的。(DISTINCT ON处理发生在ORDER BY排序之后。)

DISTINCT ON子句不是 SQL 标准的一部分,并且由于其结果的潜在不确定性而有时被认为是不好的风格。通过明智地使用FROM中的GROUP BY和子查询,可以避免此构造,但它通常是最方便的替代方案。

提交更正

如果您在文档中发现任何不正确的内容,与您对特定功能的体验不符,或者需要进一步说明,请使用此表单报告文档问题。