FROM提供column_alias,SQL 规范调用这些<derived column list>子句。这就是 postgres 文档对它们的描述,
FROM包含别名的项目的替代名称。别名用于简洁或消除自联接(多次扫描同一个表)的歧义。当提供别名时,它完全隐藏了表或函数的实际名称;例如 givenFROM foo AS f, 的其余部分SELECT必须将此FROM项目称为fnotfoo。如果编写了别名,还可以编写列别名列表来为表的一列或多列提供替代名称。
什么时候需要这些?我什么时候不能只使用 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 别名不会提供真正的好处,除非您是
这样做似乎依赖于常规t.*堆叠的危害,并增加了晦涩。那么什么时候FROM别名有用呢?
Eva*_*oll 10
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。