Redrock Postgres 搜索 英文
版本: 9.3 / 9.4 / 9.5 / 9.6 / 10 / 11 / 12 / 13 / 14 / 15 / 16 / 17

7.3. 选择列表 #

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

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

7.3.1. 选择列表项 #

最简单的选择列表种类是 *,它会列出表表达式产生的所有列。否则,选择列表是值表达式(如 第 4.2 节 所定义)的逗号分隔列表。例如,它可以是列名列表

SELECT a, b, c FROM ...

列名 abcFROM 子句中引用的表列的实际名称,或是按照 第 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 子句的表表达式中的任何列;例如,它们可以是常量算术表达式。

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 以指定保留所有行的默认行为。)

显然,如果两行的至少一个列值不同,则这两行被认为是不同的。此比较中 Null 值被视为相等。

或者,任意表达式可以决定哪些行被视为不同

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

其中 expression 是一个任意值表达式,它对所有行求值。其所有表达式都相等的一组行被视为重复行,并且仅第一行被保留在输出中。请注意,除非对足够多的列进行查询以保证到达 DISTINCT 筛选器的行的唯一排序,否则无法预测一组的 “第一行”。(DISTINCT ON 处理在 ORDER BY 排序之后进行。)

关键字 DISTINCT ON 子句不是 SQL 标准的一部分,有时因为其结果可能不稳定而被认为是不好的风格。通过在 FROM 中合理使用 GROUP BY 和子查询,可以避免使用此构造,但它通常是最方便的替代方法。