使用 Snowflake SQL left join 时出现重复数据
Duplicate data when using Snowflake SQL left join
我无法理解 Snowflake 中的 LEFT JOIN 结果。
select * from
(select 1 as AccountIdA) s
LEFT OUTER JOIN (Select 1 as AccountIdB, 'Val1' as Col1 union select 1, 'Val2' as Col1) t1 on t1.AccountIdB = s.AccountIdA
LEFT OUTER JOIN (Select 1 as AccountIdC, 'Val3' as Col2) t2 on t2.AccountIdC = s.AccountIdA
上面的 SQL 结果如下:
AccountIdA
AccountIdB
Col1
AccountIdC
Col2
1
1
VAL1
1
VAL3
1
1
VAL2
1
VAL3
但是,我期待以下结果,因为第二个左连接只有一行匹配。
AccountIdA
AccountIdB
Col1
AccountIdC
Col2
1
1
VAL1
1
VAL3
1
1
VAL2
null
null
这有什么逻辑吗?有什么方法可以获得我期望的结果吗?
so 刚刚改革 SQL so is 不那么宽,只是为了理解它。
select * from (
select 1 as AccountIdA
) s
LEFT OUTER JOIN (
SELECT * FROM VALUES (1,'val1'), (1, 'Val2') v(AccountIdB, col1)
) t1 on t1.AccountIdB = s.AccountIdA
LEFT OUTER JOIN (
SELECT * FROM VALUES (1,'val3') v(AccountIdC, col2)
) t2 on t2.AccountIdC = s.AccountIdA;
但是由于标准 SQL 逻辑,您得到两行。连接发生是连续的,因此您首先有 s
和 1
的单个 AccountIdA
。
AccountIdA
1
然后我们加入t1
,我们有
AccountIdA
AccountIdB
col1
1
1
'val1'
1
1
'val2'
这里没有惊喜:
现在我们加入 t2
给定我们有 2 行 AccountIdA
我们将 AccountIdC
与这两个匹配,并且假设它们都是 1
我们匹配两行。
AccountIdA
AccountIdB
col1
AccountIdC
col2
1
1
'val1'
1
'val3'
1
1
'val2'
1
'val3'
现在 LEFT JOIN 给你的是,如果左侧与右侧不匹配,我们得到 NULL,这可以交换一些东西,比如:
select * from (
select column1 as AccountIdA FROM VALUES (1),(2),(3)
) s
LEFT OUTER JOIN (
SELECT * FROM VALUES (1,'val1'), (2, 'Val2') v(AccountIdB, col1)
) t1 on t1.AccountIdB = s.AccountIdA
LEFT OUTER JOIN (
SELECT * FROM VALUES (3,'val3') v(AccountIdC, col2)
) t2 on t2.AccountIdC = s.AccountIdA;
现在我们在有意义的键上得到匹配,而在其他键上没有匹配。
ACCOUNTIDA
ACCOUNTIDB
COL1
ACCOUNTIDC
COL2
1
1
val1
2
2
Val2
3
3
val3
所以这表明在执行 JOIN 时你必须确保你有去重数据,否则你可以得到行的乘法
select * from (
select column1 as AccountIdA FROM VALUES (1),(1)
) s
LEFT OUTER JOIN (
SELECT * FROM VALUES (1,'val1'), (1, 'Val2') v(AccountIdB, col1)
) t1 on t1.AccountIdB = s.AccountIdA
LEFT OUTER JOIN (
SELECT * FROM VALUES (1,'val3'),(1,'val4') v(AccountIdC, col2)
) t2 on t2.AccountIdC = s.AccountIdA;
爆炸:
ACCOUNTIDA
ACCOUNTIDB
COL1
ACCOUNTIDC
COL2
1
1
val1
1
val3
1
1
val1
1
val4
1
1
Val2
1
val3
1
1
Val2
1
val4
1
1
val1
1
val3
1
1
val1
1
val4
1
1
Val2
1
val3
1
1
Val2
1
val4
我无法理解 Snowflake 中的 LEFT JOIN 结果。
select * from
(select 1 as AccountIdA) s
LEFT OUTER JOIN (Select 1 as AccountIdB, 'Val1' as Col1 union select 1, 'Val2' as Col1) t1 on t1.AccountIdB = s.AccountIdA
LEFT OUTER JOIN (Select 1 as AccountIdC, 'Val3' as Col2) t2 on t2.AccountIdC = s.AccountIdA
上面的 SQL 结果如下:
AccountIdA | AccountIdB | Col1 | AccountIdC | Col2 |
---|---|---|---|---|
1 | 1 | VAL1 | 1 | VAL3 |
1 | 1 | VAL2 | 1 | VAL3 |
但是,我期待以下结果,因为第二个左连接只有一行匹配。
AccountIdA | AccountIdB | Col1 | AccountIdC | Col2 |
---|---|---|---|---|
1 | 1 | VAL1 | 1 | VAL3 |
1 | 1 | VAL2 | null | null |
这有什么逻辑吗?有什么方法可以获得我期望的结果吗?
so 刚刚改革 SQL so is 不那么宽,只是为了理解它。
select * from (
select 1 as AccountIdA
) s
LEFT OUTER JOIN (
SELECT * FROM VALUES (1,'val1'), (1, 'Val2') v(AccountIdB, col1)
) t1 on t1.AccountIdB = s.AccountIdA
LEFT OUTER JOIN (
SELECT * FROM VALUES (1,'val3') v(AccountIdC, col2)
) t2 on t2.AccountIdC = s.AccountIdA;
但是由于标准 SQL 逻辑,您得到两行。连接发生是连续的,因此您首先有 s
和 1
的单个 AccountIdA
。
AccountIdA |
---|
1 |
然后我们加入t1
,我们有
AccountIdA | AccountIdB | col1 |
---|---|---|
1 | 1 | 'val1' |
1 | 1 | 'val2' |
这里没有惊喜:
现在我们加入 t2
给定我们有 2 行 AccountIdA
我们将 AccountIdC
与这两个匹配,并且假设它们都是 1
我们匹配两行。
AccountIdA | AccountIdB | col1 | AccountIdC | col2 |
---|---|---|---|---|
1 | 1 | 'val1' | 1 | 'val3' |
1 | 1 | 'val2' | 1 | 'val3' |
现在 LEFT JOIN 给你的是,如果左侧与右侧不匹配,我们得到 NULL,这可以交换一些东西,比如:
select * from (
select column1 as AccountIdA FROM VALUES (1),(2),(3)
) s
LEFT OUTER JOIN (
SELECT * FROM VALUES (1,'val1'), (2, 'Val2') v(AccountIdB, col1)
) t1 on t1.AccountIdB = s.AccountIdA
LEFT OUTER JOIN (
SELECT * FROM VALUES (3,'val3') v(AccountIdC, col2)
) t2 on t2.AccountIdC = s.AccountIdA;
现在我们在有意义的键上得到匹配,而在其他键上没有匹配。
ACCOUNTIDA | ACCOUNTIDB | COL1 | ACCOUNTIDC | COL2 |
---|---|---|---|---|
1 | 1 | val1 | ||
2 | 2 | Val2 | ||
3 | 3 | val3 |
所以这表明在执行 JOIN 时你必须确保你有去重数据,否则你可以得到行的乘法
select * from (
select column1 as AccountIdA FROM VALUES (1),(1)
) s
LEFT OUTER JOIN (
SELECT * FROM VALUES (1,'val1'), (1, 'Val2') v(AccountIdB, col1)
) t1 on t1.AccountIdB = s.AccountIdA
LEFT OUTER JOIN (
SELECT * FROM VALUES (1,'val3'),(1,'val4') v(AccountIdC, col2)
) t2 on t2.AccountIdC = s.AccountIdA;
爆炸:
ACCOUNTIDA | ACCOUNTIDB | COL1 | ACCOUNTIDC | COL2 |
---|---|---|---|---|
1 | 1 | val1 | 1 | val3 |
1 | 1 | val1 | 1 | val4 |
1 | 1 | Val2 | 1 | val3 |
1 | 1 | Val2 | 1 | val4 |
1 | 1 | val1 | 1 | val3 |
1 | 1 | val1 | 1 | val4 |
1 | 1 | Val2 | 1 | val3 |
1 | 1 | Val2 | 1 | val4 |