Postgres FROM 子句中的列别名?

Wil*_*ard 5 postgresql alias

我正在阅读 Postgres 文档和 SELECT 语句页面,并且遇到了我从未遇到过的别名方面。

关于 FROM 子句的部分,副标题alias 中,有一句话说明:

如果编写了别名,还可以编写列别名列表来为表的一列或多列提供替代名称。

我能找到的文档中没有给出示例。

我知道如何将输出名称设置为别名,但这似乎不是一回事。


SELECT 的概要包括以下几行:

... SELECT [ ALL | DISTINCT [ ON (expression[, ...] ) ] ] * |expression[ [ AS ]output_name] [, ...] [ FROMfrom_item[, ...] ] ...

并定义from_item为:

其中 from_item 可以是以下之一:

[ ONLY ]table_name[ * ] [ [ AS ]alias[ (column_alias[, ...] ) ] ] (select) [ AS ]alias[ (column_alias[, ...] ) ] ...(other forms omitted)...

请注意,from_item实际上包括 column_alias.


对我来说,( select )可以在 FROM 子句中为表单指定列别名是有意义的(而不仅仅是 output_names,在 SELECT 语句的“表达式”中),因为在大多数情况下将显式选择子查询的“列”因此序列将是已知的。所以我想在那种情况下 column_alias 值可能只是一个名称列表,它们将按顺序与子查询返回的列匹配。(虽然一个例子会很好。)

但是,如何为 table_name 使用列别名? 您是否必须知道表中定义的列的确切顺序或者您可以在 FROM 子句中为其中一两个设置别名吗?

如果您只想为column_alias具有很长名称的列设置 a (并且不为其他列设置别名),该怎么办?这可能吗?(如果是这样,这是 Postgres 特定的吗?)

ype*_*eᵀᴹ 7

那里的列别名会覆盖内部选择子查询(派生表)的列名/别名。同样,它们可以覆盖表的列名(无论是基表、视图、派生表还是 cte 都无关紧要)。

所以,这个简单的例子会报错:

select 
    a, count_a              -- invalid here (have been overridden)
from 
    ( select t.a, count(*) as count_a
      from t
      group by t.a
      order by count_a desc           -- count_a is valid here
      limit 8
    ) 
      as d (b, count_b) ;
Run Code Online (Sandbox Code Playgroud)

但这会起作用:

select 
    b, count_b              -- valid column aliases
from     
    -- identical as above 
Run Code Online (Sandbox Code Playgroud)

名称acount_a在子查询(派生表)内部有效,但在外部无效,因为它们已被b和覆盖count_b

您是否必须知道表中定义的列的确切顺序,或者您是否可以为FROM子句中的一两个列设置别名?

是的,您必须知道列的顺序。

但您不必更改所有列。假设表有 5 列。如果您使用:

select t.*
from table_name as t (a,b,c) ; 
Run Code Online (Sandbox Code Playgroud)

只有前 3 列会出现新名称 (a,b,c)。第 4 和第 5 将显示他们的真实姓名。如果您提供的别名比需要的多(例如,5 列表的 6 个别名),您将收到错误消息。

如果您只想为具有很长名称的一列设置 column_alias(并且不为其他列设置别名),该怎么办?这可能吗?(如果是这样,这是 Postgres 特定的吗?)

只要是第一个。或者通过提供所有以前的列名称,直到要使用不同名称别名的列。

我想你不能只为第三列提供别名,或者类似的东西?

我不知道有什么语法可以让您只为第 3 列设置别名,而不提供第 1 列和第 2 列的名称。


总的来说,当用于基表时,该功能的有用性至少是有争议的。上面的查询只覆盖了可能很多列中的 3 个列的名称,这很令人困惑,很可能被认为是不好的做法。

但是提供该功能是因为它是标准 SQL 并且是为了完整性。仅将其用于子查询和 CTE 而不适用于其他类型的表是没有意义的。

一种情况可能是有用的(不与基表,但同)的VALUES结构,其中列得到的默认名称column1column2等这个别名可以用来选择更有意义的名称:

select 
    a, b
from 
    ( values
         (1, 2),
         (2, 3), 
         (3, 5)
    ) 
      as d (a, b) ;
Run Code Online (Sandbox Code Playgroud)