0

在 Snowflake (ANSI) SQL 中,我惊讶地发现

SELECT
  *
FROM
  t1
INNER JOIN
  t2
USING(a. b, c)

编译得很好(我在想.之后a会导致 SQL 编译错误)。乍一看,结果似乎与相同的代码相同USING(a, b, c)。此外,USING(a, b. c)编译并产生不同的结果,并USING(a. b. c)给出 SQL 编译错误。

有人对这种行为有解释吗?SQL如何解释此处.的列列表中的USING

4

3 回答 3

0

看起来像“a.b”===“ab”。

我在下面测试过:

create or replace table t1 (a int, b int, c int);

select t1. a, t1.   c from t1;
select t1.a, t1.c from t1;

以上两个 SELECT 语句都返回了相同的结果。

这意味着在您的示例中:

SELECT
  *
FROM
  t1
INNER JOIN
  t2
USING(a. b, c)

它与以下内容相同:

SELECT
  *
FROM
  t1
INNER JOIN
  t2
USING(a.b, c)

USING(ab c) 失败,因为 abc 不存在。

于 2021-09-08T23:16:17.053 回答
0

很好的发现,我也找不到关于它的文档,但我做了进一步的实验,发现了一些有趣的行为。

    with t1 as (
select 1 as a
  , 2 as b
  , 3 as c
)
, t2 as (
select 1 as a
  , 5 as b
  , 6 as c
)
SELECT
  *
FROM
  t1
INNER JOIN
  t2
USING(a, b, c);

为所有人生成匹配项

在此处输入图像描述

但是当您操作代码时,USING(a. b, c) 它会将 A 放在末尾,并且该列出现两次!

在此处输入图像描述

当我更改列中的值并将点保持在输出的位置时......什么都没有

with t1 as (
select 1 as a
  , 2 as b
  , 3 as c
)
, t2 as (
select 1 as a
  , 5 as b
  , 6 as c
)
SELECT
  *
FROM
  t1
INNER JOIN
  t2
USING(a. b, c);

现在再改一下

with t1 as (
select 1 as a
  , 2 as b
  , 3 as c
)
, t2 as (
select 4 as a
  , 2 as b
  , 3 as c
)
SELECT
  *
FROM
  t1
INNER JOIN
  t2
USING(a. b, c);

B 和 C 应该匹配但 A 不匹配 非匹配列出现两次

在此处输入图像描述

开始在这里看到一个模式吧?

似乎在连接中使用了没有点的列,但另一列没有。似乎您只能使用带有点表示法的一列,添加更多点列会出错。

于 2021-09-08T23:31:24.347 回答
0

点表示法接受表名和列名之间的空格。我在 Oracle 和 PostgreSQL 上进行了测试。所以这是一个有效的用法:

select 1 as a
  , 2 as b
  , 3 as c
)
select t1. a, t1.a from t1;

+---+---+
| A | A |
+---+---+
| 1 | 1 |
+---+---+

据我所知,其他数据库在 USING 子句中不接受点表示法,而 Snowflake 忽略表名并获取列名(即使表名/别名不存在)。因此,当您编写“USING (ab, c)”时 - 它只使用 b 和 c 列来连接表。

如果它支持点表示法,为什么它不支持 2 级点表示法?

create or replace table t1 (a int, b int, c int) as select 1,2,3;
create or replace table t2 (a int, b int, c int) as select 1,2,3;
select public.t1.a from t1; -- works

select *
from  t1 join t2
using( public.t1.a ); -- fails

这与之前的行为不一致。正确的行为应该是像其他数据库供应商那样“不接受任何点”。您可以将其报告为错误吗?

于 2021-09-09T01:10:16.973 回答