Postgresql 中文操作指南
7.3. Select Lists #
如前一节所示,@{20} 命令中的表表达式通过组合表、视图、消除行、分组等可能构造一个中间虚拟表。该表最终将传递给 @{21} 处理。选择列表确定实际输出的中间表的 @{22}。
7.3.1. Select-List Items #
最简单的选择列表是 *,它会发出表表达式生成的全部列。否则,选择列表是不定值表达式的逗号分隔列表(如下 Section 4.2 中定义)。例如,它可以是列名称列表:
SELECT a, b, c FROM ...
列名称 a、b 和 c 要么是 FROM 子句中引用的表的列的实际名称,要么是按照 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. Column Labels #
可以选择列表中的条目以供后续处理,例如用于 ORDER BY 子句或供客户端应用程序显示。例如:
SELECT a AS value, b + c AS sum FROM ...
如果没有使用 AS 指定输出列名称,则系统将分配一个默认列名称。对于简单的列引用,这是引用的列的名称。对于函数调用,这是函数的名称。对于复杂表达式,系统会生成一个通用名称。
AS 关键字通常是可选的,但在某些情况下,当所需的列名称与 PostgreSQL 关键字相同时,您必须编写 AS 或对列名称加双引号以避免歧义。( Appendix 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 或为输出列名称加上双引号。
Note
此处输出列的命名方式不同于_FROM_子句中的命名方式(请参阅 Section 7.2.1.2)。可以将同一列重命名两次,但是选择列表中指定的名称是将被传递的名称。
7.3.3. DISTINCT #
在处理完选择列表之后,结果表可以选择进行重复行的消除。为此,在 SELECT 后直接写入 DISTINCT 关键字:
SELECT DISTINCT select_list ...
(可以将关键字 ALL 用作 DISTINCT,而不是将其用于指定保留所有行的默认行为。)
显然,如果两个行的至少一个列值不同,则它们被视为是不同的。在该比较中空值被视为相等的。
或者,可以用任意表达式来确定哪些行被视为不同的:
SELECT DISTINCT ON (expression [, expression ...]) select_list ...
此处 expression 是对所有行求值的自变量表达式。其中所有表达式均相等的那些行都被视为重复行,并且只保留该组的第一行作为输出。请注意,除非对足够多的列对查询进行排序以保证到达 DISTINCT 过滤器的行具有唯一的排序顺序,否则一组的“第一行”是不可预测的。(DISTINCT ON 处理发生在 ORDER BY 排序之后。)
DISTINCT ON 子句不属于 SQL 标准,有时被认为是不佳风格,因为其结果本质上是不可确定的。通过明智地使用 FROM 中的 GROUP BY 和子查询,可以避免这种结构,但它通常是最方便的备选方案。