小编典典

Amazon Redshift-横向列别名参考

sql

基于

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'


它看起来像是有趣的语言扩展,但有一个警告。如果我的功能不确定,该怎么办:

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的比较(是的,我知道这是不同的功能,我希望“侧面库伦别名”的行为相同):

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子句中的列具有优先权。

我的理解正确吗?当我们使用不确定性或时间敏感的功能/引用/子查询时,此功能不是“安全的”吗?


阅读 171

收藏
2021-05-05

共1个答案

小编典典

此语法不安全。实际上,仅内联代码意味着它甚至没有提供性能优势。它只是语法糖。

考虑到CTE和子查询是很容易的选择,我只是避免使用这种新的“功能”。

如果有关闭此功能的设置,我建议您使用它。

顺便说一下,SQL的许多新手发现这很令人不安。目的是避免歧义。以下查询应返回什么?

select (a + 1) as b, b 
from (select 1 as a, 0 as b) x;

SQL的设计者可能认为解决这种情况的规则比仅重写子查询要复杂得多。

我知道可以很好地解决这一问题的一个“数据库”实际上是SAS proc SQL。它引入了calculated关键字,因此您可以编写:

select (a + 1) as b, calculated b, b
from (select 1 as a, 0 as b) x;

这将返回2, 2, 0

换句话说,我认为亚马逊并没有为实现这一“功能”投入太多心思。

2021-05-05