何时需要 FROM 子句中的 COLUMN 别名?

Eva*_*oll 6 postgresql alias

FROM提供column_alias,SQL 规范调用这些<derived column list>子句。这就是 postgres 文档对它们的描述,

FROM包含别名的项目的替代名称。别名用于简洁或消除自联接(多次扫描同一个表)的歧义。当提供别名时,它完全隐藏了表或函数的实际名称;例如 given FROM foo AS f, 的其余部分SELECT必须将此FROM项目称为fnot foo。如果编写了别名,还可以编写列别名列表来为表的一列或多列提供替代名称。

什么时候需要这些?我什么时候不能只使用 COLUMN 别名?

SELECT t.*
FROM table_name AS t (a,b,c);
Run Code Online (Sandbox Code Playgroud)

对比

SELECT t.col1 AS a, t.col2 AS b, t.col3 AS c
FROM table_name AS t;
Run Code Online (Sandbox Code Playgroud)

这个例子取自@ypercube 选择的答案??这似乎不太有用。

上述上下文中的 FROM 别名不会提供真正的好处,除非您是

  • 依赖部分别名(不别名整个表)
  • 这取决于升序列排序
  • 你的表有超过三列(或者你可以在 from 子句中明确地写出来)。

这样做似乎依赖于常规t.*堆叠的危害,并增加了晦涩。那么什么时候FROM别名有用呢?

Eva*_*oll 10

如果列不存在(VALUES 子句)

PostgreSQL 为它们提供了默认名称,但这不是重点。您不能在不存在的 COLUMN 列表中为它们设置别名。

SELECT t.*
FROM (VALUES ('row1',1), ('row2',2)) AS t;
Run Code Online (Sandbox Code Playgroud)

这将是VALUES LIST语法的一个很好的例子,它要求您在FROM列表中使用别名。

SELECT t.*
FROM (VALUES ('row1',1), ('row2',2)) AS t(english,rownum);
Run Code Online (Sandbox Code Playgroud)

从那里您甚至可以在选择列表中使用别名。

SELECT rownum
FROM (VALUES ('row1',1), ('row2',2)) AS t(english,rownum);
Run Code Online (Sandbox Code Playgroud)

而且,这给我们带来了一个复杂的例子,比如在PostGIS in Action, Second Edition 的第 190 页上找到的例子。

SELECT
  oid --**only possible because of FROM ALIASING.**
  , lowrite(lo_open(oid, 131072), img) As num_bytes
FROM (
  VALUES (
    lo_create(0),
    (
      SELECT
        ST_AsGDALRaster(
          ST_Band(rast,1)
          , 'USGSDEM'
          , ARRAY[
            'PRODUCER=' || quote_literal('postgis_in_action')
            , 'INTERNALNAME=' || quote_literal(rast_name)
          ]
        ) As dem
      FROM ch07.bag_o_rasters
      WHERE rast_name = 'Raster 1 band heatmap'
    )
  )
) As v(oid,img); --**FROM ALIASING**
Run Code Online (Sandbox Code Playgroud)

如果这很难接受,那么还有另一种尴尬的结构,那就是 SELECT 作为 COLUMN。

SELECT ( SELECT 1 ), ( SELECT 2 ); -- one row "1,2"

SELECT lo_create(0), ( SELECT 2 ); -- one row "oid,2"
Run Code Online (Sandbox Code Playgroud)

lo_create返回一个oid。不过,这超出了本答案的范围。

对于另一个真实世界的示例,请参阅我刚刚回答的这个问题

在自联接中

这可能值得一提,因为它在文档中,

SELECT * FROM temp;
 foo |  bar   
-----+--------
   1 | evan
   2 | dba.se
(2 rows)
Run Code Online (Sandbox Code Playgroud)

你自己加入你会得到两bar列。

SELECT * FROM temp JOIN temp AS t2 USING (foo);
 foo |  bar   |  bar   
-----+--------+--------
   1 | evan   | evan
   2 | dba.se | dba.se
(2 rows)
Run Code Online (Sandbox Code Playgroud)

但是,使用 FROM 别名,您可以分别标记它们,

SELECT * FROM temp JOIN temp AS t2(foo,bar2) USING (foo);
 foo |  bar   |  bar2  
-----+--------+--------
   1 | evan   | evan
   2 | dba.se | dba.se
(2 rows)
Run Code Online (Sandbox Code Playgroud)

然而,这并不比 COLUMN-aliasing 方法好,

SELECT foo, temp.bar, t2.bar AS bar2
FROM temp JOIN temp AS t2
  USING (foo);
Run Code Online (Sandbox Code Playgroud)

唯一的区别是,在 FROM-aliasing 方法中,您唯一地引用t2.baras 的所有实例bar2