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