Luk*_*zda 2 sql amazon-redshift
基于
对横向列别名引用的支持使您能够编写查询,而无需在 SELECT 列表中重复相同的表达式。例如,您可以定义别名“probability”并在同一 select 语句中使用它:
Run Code Online (Sandbox Code Playgroud)select clicks / impressions as probability, round(100 * probability, 1) as percentage from raw_data;
这与以下内容基本相同:
select 1 AS col
,col + 1 AS col2;
Run Code Online (Sandbox Code Playgroud)
大多数 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
Run Code Online (Sandbox Code Playgroud)
与 PostgreSQL 相比LATERAL JOIN(是的,我知道这是不同的功能,我希望“横向别名”的行为方式相同):
SELECT s.col, s.col+1 AS col2
FROM t ,LATERAL (SELECT RANDOM()) AS s(col)
-- 0.19089933477628307 1.190899334776283
Run Code Online (Sandbox Code Playgroud)
但事实并非如此。我得到了两次独立的运行,如果它是简单的“内联”,这似乎是有效的:
别名在目标列表中定义后立即被识别。您可以在同一目标列表中在其后定义的其他表达式中使用别名。下面的例子说明了这一点。
横向别名引用的好处是,在同一目标列表中构建更复杂的表达式时,您不需要重复别名表达式。当 Amazon Redshift 解析此类引用时,它仅内联之前定义的别名。如果 FROM 子句中定义的列与先前的别名表达式同名,则 FROM 子句中的列优先。
当我们使用不确定性或时间敏感的函数/引用/子查询时,我的理解是否正确,并且此功能不“安全”?
这种语法并不安全。事实上,仅仅内联代码意味着它甚至不能提供性能优势。它只是语法糖。
鉴于有简单的替代方案——CTE 和子查询——我会避免这个新的“功能”。
如果有一个设置可以关闭此功能,我建议使用它。
顺便说一句,许多 SQL 新手发现这相当令人不安。这样做的目的是为了避免歧义。以下查询应该返回什么?
select (a + 1) as b, b
from (select 1 as a, 0 as b) x;
Run Code Online (Sandbox Code Playgroud)
SQL 的设计者可能认为解决此类情况的规则比仅仅重写子查询更复杂。
据我所知,能很好地解决这个问题的一个“数据库”实际上是 SAS proc SQL。它引入了calculated关键字,所以你可以这样写:
select (a + 1) as b, calculated b, b
from (select 1 as a, 0 as b) x;
Run Code Online (Sandbox Code Playgroud)
而这将会回归2, 2, 0。
换句话说,我认为亚马逊并没有在这个“功能”的实现上花太多心思。
| 归档时间: |
|
| 查看次数: |
7407 次 |
| 最近记录: |