7.3. 选择列表

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

7 .3.1. 选择清单项目

选择列表中最简单的一种是*,它发出表表达式生成的所有列。否则,选择列表是逗号分隔的值表达式列表(如Section 4.2所定义)。例如,它可以是列名称的列表:

SELECT a, b, c FROM ...

列名abcFROM子句中引用的表的列的实际名称,或者是Section 7.2.1.2中说明的为其赋予的别名。除非使用分组,否则选择列表中可用的名称空间与WHERE子句中的名称空间相同,在这种情况下,它与HAVING子句中的名称空间相同。

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

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

当使用多个表时,询问特定表的所有列也可能很有用:

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

有关* table_name * .*表示法的更多信息,请参见Section 8.16.5

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

7 .3.2. 列标签

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

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

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

AS关键字是可选的,但仅当新列名与任何 PostgreSQL 关键字都不匹配时(请参见Appendix C)。为避免意外匹配关键字,您可以将列名双引号。例如,VALUE是关键字,因此它不起作用:

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

但是这样做:

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

为了防止将来可能添加关键字,建议您始终写AS或双引号输出列名称。

Note

此处输出列的命名与FROM子句中的命名(请参见Section 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过滤器的行的唯一 Sequences,否则集合的“第一行”是不可预测的。 (ORDER BY排序后进行DISTINCT ON处理.)

DISTINCT ON子句不是 SQL 标准的一部分,有时会被认为是不好的样式,因为它的结果可能不确定。明智地使用GROUP BYFROM中的子查询,可以避免这种构造,但是它通常是最方便的选择。