基于
Amazon Redshift宣布支持横向列别名参考: 对横向列别名引用的支持使您能够编写查询,而不必在SELECT列表中重复相同的表达式。例如,您可以定义别名“概率”,并在同一select语句中使用它: select clicks / impressions as probability, round(100 * probability, 1) as percentage from raw_data;
Amazon Redshift宣布支持横向列别名参考:
对横向列别名引用的支持使您能够编写查询,而不必在SELECT列表中重复相同的表达式。例如,您可以定义别名“概率”,并在同一select语句中使用它:
select clicks / impressions as probability, round(100 * probability, 1) as percentage from raw_data;
基本上与以下内容相同:
select 1 AS col ,col + 1 AS col2;
db <> fiddle演示
大多数SQL RDBMS都将返回错误: Unknown column 'col' in 'field list'
Unknown column 'col' in 'field list'
它看起来像是有趣的语言扩展,但有一个警告。如果我的功能不确定,该怎么办:
select RAND() AS col ,col + 1 AS col2 -- if RAND() returns 0.5 then I would expect -- 0.5 and 1.5 -- I get: 0.3 and 1.7 -- it means that the query was evaluated as: select RAND() AS col, RAND() + 1 AS col2
与LATERAL JOIN来自PostgreSQL的比较(是的,我知道这是不同的功能,我希望“侧面库伦别名”的行为相同):
LATERAL JOIN
SELECT s.col, s.col+1 AS col2 FROM t ,LATERAL (SELECT RANDOM()) AS s(col) -- 0.19089933477628307 1.190899334776283
db <>fiddle演示
但事实并非如此。我得到了两次独立运行,如果简单地进行“内联”,这似乎是有效的:
选择清单 别名在目标列表中定义后立即被识别。您可以在同一目标列表中在别名之后定义的其他表达式中使用别名。以下示例说明了这一点。 横向别名引用的好处是,在同一目标列表中构建更复杂的表达式时,无需重复使用别名表达式。当Amazon Redshift解析这种类型的引用时, 它仅内联先前定义的别名。 如果在FROM子句中定义的名称与以前的别名表达式相同,则FROM子句中的列具有优先权。
选择清单
别名在目标列表中定义后立即被识别。您可以在同一目标列表中在别名之后定义的其他表达式中使用别名。以下示例说明了这一点。
横向别名引用的好处是,在同一目标列表中构建更复杂的表达式时,无需重复使用别名表达式。当Amazon Redshift解析这种类型的引用时, 它仅内联先前定义的别名。 如果在FROM子句中定义的名称与以前的别名表达式相同,则FROM子句中的列具有优先权。
我的理解正确吗?当我们使用不确定性或时间敏感的功能/引用/子查询时,此功能不是“安全的”吗?
此语法不安全。实际上,仅内联代码意味着它甚至没有提供性能优势。它只是语法糖。
考虑到CTE和子查询是很容易的选择,我只是避免使用这种新的“功能”。
如果有关闭此功能的设置,我建议您使用它。
顺便说一下,SQL的许多新手发现这很令人不安。目的是避免歧义。以下查询应返回什么?
select (a + 1) as b, b from (select 1 as a, 0 as b) x;
SQL的设计者可能认为解决这种情况的规则比仅重写子查询要复杂得多。
我知道可以很好地解决这一问题的一个“数据库”实际上是SAS proc SQL。它引入了calculated关键字,因此您可以编写:
proc SQL
calculated
select (a + 1) as b, calculated b, b from (select 1 as a, 0 as b) x;
这将返回2, 2, 0。
2, 2, 0
换句话说,我认为亚马逊并没有为实现这一“功能”投入太多心思。