Skip to content

7.3. 选择列表#

7.3.1. 选择列表项
7.3.2. 列标签
7.3.3. DISTINCT

如前一节所示,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 标准的一部分,有时由于其结果的潜在不确定性而被认为是不良风格。通过明智地使用GROUP BYFROM中的子查询,可以避免这种构造,但它通常是最方便的替代方案。