选择 打开 改范围 完整检索页
受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10
当前 PostgreSQL 版本不在支持生命周期内。
您可以参阅当前版本的对应页面,或其他在上面列出的活跃大版本。

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关键字相同(见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 #

在处理完选择列表之后,结果表还可以选择性地删除重复行。我们可以直接在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中的子查询,可以避免使用这种结构,但它往往是最方便的替代方案。