如前一节所示,SELECT
命令中的表表达式通过可能的组合表、视图、消除行、分组等来构造一个中间虚拟表。此表最终传递给 select list 进行处理。选择列表确定实际输出中间表的哪些 列。
最简单的选择列表种类是 *
,它会列出表表达式产生的所有列。否则,选择列表是值表达式(如 第 4.2 节 所定义)的逗号分隔列表。例如,它可以是列名列表
SELECT a, b, c FROM ...
列名 a
、b
和 c
是 FROM
子句中引用的表列的实际名称,或是按照 第 7.2.1.2 节 中的说明给它们指定的别名。选择列表中可用的名称空间与 WHERE
子句相同,除非使用了分组,在这种情况下,它与 HAVING
子句中的名称空间相同。
如果多个表具有同名的列,则列名也必须给出,如下所示
SELECT tbl1.a, tbl2.a, tbl1.b FROM ...
使用多张表时,请求特定表的全部列可能也有用
SELECT tbl1.*, tbl2.a FROM ...
请参阅 第 8.16.5 节 以详细了解 table_name
.*
符号。
如果在选择列表中使用了任意值表达式,它会在概念上向返回的表添加新虚拟列。系统会针对每一行结果评估值表达式一次,并用该行的值替换所有列引用。但是,选择列表中的表达式不必引用 FROM
子句的表表达式中的任何列;例如,它们可以是常量算术表达式。
可以选择列表中的条目,例如,以便在 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 节)。可以对同一列重新命名两次,但选择列表中分配的名称将被传入。
DISTINCT
#在处理选择列表后,结果表可以选择进行重复行消除。关键字 DISTINCT
直接写在 SELECT
之后以指定此操作
SELECT DISTINCT select_list
...
(可以使用关键字 ALL
取代 DISTINCT
以指定保留所有行的默认行为。)
显然,如果两行的至少一个列值不同,则这两行被认为是不同的。此比较中 Null 值被视为相等。
或者,任意表达式可以决定哪些行被视为不同
SELECT DISTINCT ON (expression
[,expression
...])select_list
...
其中 expression
是一个任意值表达式,它对所有行求值。其所有表达式都相等的一组行被视为重复行,并且仅第一行被保留在输出中。请注意,除非对足够多的列进行查询以保证到达 DISTINCT
筛选器的行的唯一排序,否则无法预测一组的 “第一行”。(DISTINCT ON
处理在 ORDER BY
排序之后进行。)
关键字 DISTINCT ON
子句不是 SQL 标准的一部分,有时因为其结果可能不稳定而被认为是不好的风格。通过在 FROM
中合理使用 GROUP BY
和子查询,可以避免使用此构造,但它通常是最方便的替代方法。