受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发版本: devel

7.3. 选择列表 #

如前面几节所示,SELECT命令中的表表达式会构造出一个中间虚拟表,其中可能涉及组合表和视图、消除行、分组等操作。这个表随后交由选择列表处理。选择列表决定中间表中的哪些会实际输出。

7.3.1. 选择列表项 #

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

SELECT a, b, c FROM ...

列名abc要么是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. 列标签 #

选择列表中的项可以被赋予名字,以供后续处理使用,例如在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 ...

(如果不用DISTINCT,则可以用ALL关键字来显式指定保留所有行这一默认行为。)

显然,如果两行至少在一个列值上不同,就认为它们是不同的。空值在这种比较中被认为是相等的。

另外,我们还可以用任意表达式来判断什么行可以被认为是可区分的:

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

这里的expression是一个对所有行求值的任意值表达式。如果某一组行在这些表达式上的值都相等,那么它们就会被视为重复行,因此只保留该组中的第一行。请注意,某一组里的第一行是不可预测的,除非查询在足够多的列上进行了排序,以保证到达DISTINCT过滤器的行顺序是唯一的。(DISTINCT ON的处理发生在ORDER BY排序之后。)

DISTINCT ON子句不是 SQL 标准的一部分,有时会被认为风格不佳,因为它的结果可能具有不确定性。通过审慎使用GROUP BY以及FROM中的子查询,可以避免使用这种结构,但它往往是最方便的替代方案。

提交更正

如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。