Использование «.» против «,» в SQL-соединении Snowflake … ИСПОЛЬЗОВАНИЕ() списка столбцов

#sql #snowflake-cloud-data-platform #snowflake-sql

Вопрос:

В SQL Snowflake (ANSI) я был удивлен, обнаружив, что

 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 здесь?

Ответ №1:

Выглядит как «a. b» === «a.b».

Я протестировал ниже:

 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)
 

ИСПОЛЬЗОВАНИЕ(a. b. c) не удалось, потому что a.b.c не существует.

Ответ №2:

Отличная находка, я тоже не могу найти документацию по ней, но я провел дальнейшие эксперименты и обнаружил некоторое интересное поведение.

     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) , он ставит букву » А » в конце, и столбец появляется дважды!

введите описание изображения здесь

Когда я изменяю значения в столбцах и оставляю точку там, где она есть, вывод… ничего

 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);
 

В и С должны совпадать, но А не
Столбец несоответствий отображается дважды

введите описание изображения здесь

Начинаешь видеть здесь закономерность, верно?

Похоже, что столбцы без точки используются в соединении, но другой столбец не используется. Похоже, что вы можете использовать только один столбец с точечной нотацией, добавив больше пунктирных столбцов, которые не удалось использовать по ошибке.

Ответ №3:

Точечная нотация допускает пробелы между именем таблицы и именем столбца. Я протестировал на 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 (a.b, 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
 

Это несовместимо с предыдущим поведением. Правильное поведение должно заключаться в том, чтобы «не принимать никаких точек», как это делают другие поставщики баз данных. Можете ли вы сообщить об этом как об ошибке?

Комментарии:

1. Спасибо, Гохан, я также подтвердил это несоответствие в своей собственной базе данных-отправил сообщение сообщества здесь ( community.snowflake.com/s/feed/0D53r0000AwRC8HCQW )