使用 Snowflake SQL 根据其他行中的值在连接期间删除行
Remove rows during a join based on values in other rows using Snowflake SQL
我将多个 table 连接在一起并得到类似于
的结果
USER_ID YEAR FIELD1 FIELD2 ...
1 2020 -- X
1 2020 -- Y
1 2020 -- Z
1 2020 Value X
1 2020 Value Y
1 2020 Value Z
1 2021 -- X
1 2021 -- Y
1 2021 -- Z
2 2020 -- X
2 2020 -- Y
2 2020 -- Z
2 2020 Value X
2 2020 Value Y
2 2020 Value Z
3 2020 -- X
3 2020 -- Y
3 2020 -- Z
如果 FIELD1 不是“--”的 USER_ID 和 YEAR 值相同,我想删除 FIELD1 是“--”的行。所以我应该得到这样的结果:
USER_ID YEAR FIELD1 FIELD2 ...
1 2020 Value X
1 2020 Value Y
1 2020 Value Z
1 2021 -- X
1 2021 -- Y
1 2021 -- Z
2 2020 Value X
2 2020 Value Y
2 2020 Value Z
3 2020 -- X
3 2020 -- Y
3 2020 -- Z
我不想从 table 中删除 USER_ID、YEAR 和 FIELD1 来自的行。我只想将适当的 where 子句添加到长连接查询的末尾。我目前在我的连接查询末尾有这样的东西,它在没有 where 子句的情况下工作:
select...
from TABLE1 as t
join...
where t.FIELD1 = '--' and exists(
select *
from TABLE1 as t2
where t.USER_ID= t2.USER_ID and
t.YEAR = t2.YEAR and
t2.FIELD1 != '--')
您可以 OR` 因为它与另一个条件互斥
SELECT * FROM table1 t1
WHERE (FIELD1 = '--'
AND NOT EXISTS( SELECT 1 FROM table1 t2 WHERE t1.USER_ID = t2.USER_ID AND t1.YEAR = t2.YEAR
AND t2.FIELD1 <> '--'))
OR FIELD1 <> '--'
ORDER BY USER_ID, YEAR
您可以像这样使用 DENSE_RANK and QUALIFY:
SELECT *
FROM data
QUALIFY dense_rank() over (partition by user_id, year, field2 order by FIELD1 = '--') = 1
相当简洁,不需要任何连接或 sub-queries。
USER_ID
YEAR
FIELD1
FIELD2
1
2,020
Value
X
1
2,020
Value
Y
1
2,020
Value
Z
1
2,021
--
X
1
2,021
--
Y
1
2,021
--
Z
2
2,020
Value
X
2
2,020
Value
Y
2
2,020
Value
Z
3
2,020
--
X
3
2,020
--
Y
3
2,020
--
Z
这是可行的,因为对于每个 user_id, year, field2
,我们将其上的数据排序为次要的 '--'
,因为 true
排序晚于 false
排名第一的是“所有 non-double 连字符字符串”或该分组的 hypen-string。
我将多个 table 连接在一起并得到类似于
的结果USER_ID YEAR FIELD1 FIELD2 ...
1 2020 -- X
1 2020 -- Y
1 2020 -- Z
1 2020 Value X
1 2020 Value Y
1 2020 Value Z
1 2021 -- X
1 2021 -- Y
1 2021 -- Z
2 2020 -- X
2 2020 -- Y
2 2020 -- Z
2 2020 Value X
2 2020 Value Y
2 2020 Value Z
3 2020 -- X
3 2020 -- Y
3 2020 -- Z
如果 FIELD1 不是“--”的 USER_ID 和 YEAR 值相同,我想删除 FIELD1 是“--”的行。所以我应该得到这样的结果:
USER_ID YEAR FIELD1 FIELD2 ...
1 2020 Value X
1 2020 Value Y
1 2020 Value Z
1 2021 -- X
1 2021 -- Y
1 2021 -- Z
2 2020 Value X
2 2020 Value Y
2 2020 Value Z
3 2020 -- X
3 2020 -- Y
3 2020 -- Z
我不想从 table 中删除 USER_ID、YEAR 和 FIELD1 来自的行。我只想将适当的 where 子句添加到长连接查询的末尾。我目前在我的连接查询末尾有这样的东西,它在没有 where 子句的情况下工作:
select...
from TABLE1 as t
join...
where t.FIELD1 = '--' and exists(
select *
from TABLE1 as t2
where t.USER_ID= t2.USER_ID and
t.YEAR = t2.YEAR and
t2.FIELD1 != '--')
您可以 OR` 因为它与另一个条件互斥
SELECT * FROM table1 t1
WHERE (FIELD1 = '--'
AND NOT EXISTS( SELECT 1 FROM table1 t2 WHERE t1.USER_ID = t2.USER_ID AND t1.YEAR = t2.YEAR
AND t2.FIELD1 <> '--'))
OR FIELD1 <> '--'
ORDER BY USER_ID, YEAR
您可以像这样使用 DENSE_RANK and QUALIFY:
SELECT *
FROM data
QUALIFY dense_rank() over (partition by user_id, year, field2 order by FIELD1 = '--') = 1
相当简洁,不需要任何连接或 sub-queries。
USER_ID | YEAR | FIELD1 | FIELD2 |
---|---|---|---|
1 | 2,020 | Value | X |
1 | 2,020 | Value | Y |
1 | 2,020 | Value | Z |
1 | 2,021 | -- | X |
1 | 2,021 | -- | Y |
1 | 2,021 | -- | Z |
2 | 2,020 | Value | X |
2 | 2,020 | Value | Y |
2 | 2,020 | Value | Z |
3 | 2,020 | -- | X |
3 | 2,020 | -- | Y |
3 | 2,020 | -- | Z |
这是可行的,因为对于每个 user_id, year, field2
,我们将其上的数据排序为次要的 '--'
,因为 true
排序晚于 false
排名第一的是“所有 non-double 连字符字符串”或该分组的 hypen-string。