1

通常,当我尝试在 SnowFlake 中选择多个列并且我忘记使用逗号(而不是a,b,c我写a b c)时,它会给我一个错误。

输入:

select a b c from (
SELECT column1 as c, column2 as a, column3 as b 
FROM (VALUES ('Q','g','a'),('C','D','x'))
);

输出:

SQL 编译错误:位置 11 的语法错误第 1 行意外'c'。

但是当我尝试仅在两列之间执行此操作时,它不会引发任何错误,而是返回错误的结果:

select a b from (
SELECT column1 as a, column2 as b, column3 as c 
FROM (VALUES ('Q','g','a'),('C','D','x'))
);

输出:

SF 输出错误值

它只显示单列,其中包含来自 column 的值,a但表示它是 column b。我在不同的仓库、不同的窗口、不同的列名和值的名称上尝试了几次,结果还是一样。

这种行为的原因是什么?为什么它不像在 3 列的情况下那样引发错误消息?我发现这种行为非常令人困惑。我可以以某种方式告诉 SF 引发错误(就像 3 列或更多列的情况一样)?

4

2 回答 2

3

好的做法是使用前缀和AS关键字。一开始可能看起来是多余的,但“显式胜于隐式”

例如,当列有前缀时,这种“错字”会立即出错:

select s.a s.b from (
    SELECT column1 as c, column2 as a, column3 as b 
    FROM (VALUES ('Q','g','a'),('C','D','x'))
) AS s;
-- Syntax error: unexpected '.'. (line 1)

理想的情况是使用AS关键字:

SELECT s.a, s.b, s.c 
FROM(
    SELECT column1 as c, column2 as a, column3 as b 
    FROM (VALUES ('Q','g','a'),('C','D','x'))
) AS s;

整个查询可以进一步简化:

SELECT s.a, s.b, s.c
FROM (VALUES ('Q','g','a'),('C','D','x')) AS s(a,b,c);

附加功能:

下面的查询可以被视为代码异味

SELECT col1 col2
FROM tab;

有些工具能够检测到此类事件。例如:SQLFluff

SQLFluff 中的规则是作为爬虫实现的。这些实体通过查询的解析结构来评估特定规则或规则集。

...

类 Rule_L012(代码、描述、**kwargs)

不允许列的隐式别名。使用显式 AS 子句。

注意:此规则从 obj:Rule_L011 继承其功能,但是是独立的,因此可以单独启用和禁用它们。

于 2021-08-26T14:03:58.813 回答
2

实际上,这是有效的 SQL。您正在做的是SELECTing 列 a,但在最终选择中为其添加别名“b”。别名的“as”在 SQL 中是可选的。

请注意,这就是为什么当您列出 3 列时,您会在“c”而不是“b”上收到错误。因为即使在该查询中,'a as b' 等效项也是有效的。

于 2021-08-26T13:16:39.177 回答