如前一节所示,SELECT
命令中的表表达式通过可能组合表、视图、消除行、分组等来构造一个中间的虚拟表。这个表最终被传递给select list(SELECT 列表)进行处理。SELECT 列表决定了中间表的哪些列实际上被输出。
最简单的 SELECT 列表是 *
,它会输出表表达式生成的所有列。否则,SELECT 列表是一个由值表达式(定义见 第 4.2 节)组成的逗号分隔列表。例如,它可以是一个列名列表
SELECT a, b, c FROM ...
列名 a
、b
和 c
要么是 FROM
子句中引用的表的列的实际名称,要么是如 第 7.2.1.2 节中所解释的为它们指定的别名。在 SELECT 列表中可用的命名空间与 WHERE
子句中的相同,除非使用了分组,在这种情况下,它与 HAVING
子句中的相同。
如果多个表具有同名的列,则还必须提供表名,例如:
SELECT tbl1.a, tbl2.a, tbl1.b FROM ...
在处理多个表时,要求获取特定表的所有列也可能很有用:
SELECT tbl1.*, tbl2.a FROM ...
有关 table_name
.*
表示法的更多信息,请参阅 第 8.16.5 节。
如果在 SELECT 列表中使用了任意值表达式,它会概念性地向返回的表中添加一个新的虚拟列。该值表达式会为每一结果行求值一次,并将该行的值替换掉任何列引用。但 SELECT 列表中的表达式不必引用 FROM
子句的表表达式中的任何列;它们可以是常量算术表达式,例如。
SELECT 列表中的项可以被分配名称,以便后续处理,例如在 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 节)。可以对同一列重命名两次,但 SELECT 列表中指定的名称将是传递给后续处理的名称。
DISTINCT
#在 SELECT 列表处理完毕后,结果表可以选择性地进行重复行消除。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 标准的一部分,有时被认为是不好的风格,因为它可能产生不确定的结果。通过谨慎使用 GROUP BY
和 FROM
中的子查询,可以避免这种构造,但它通常是最方便的替代方案。
如果您在文档中看到任何不正确、与您对特定功能的体验不符或需要进一步澄清的内容,请使用 此表单 来报告文档问题。